我正在使用 emu8086 为 8086 编写 .asm。
我想使用
loop
指令循环字节数组。在循环内部,我想访问数组中的数据,按顺序(从最低内存地址到最高内存地址)。
我可以使用以下代码来做到这一点:
array DB 9,1,4,7,2
length DW 5
mov cx, length ;cx <-- desired iterations
lea si, array ;si <-- address of first array byte
my_loop: mov al, [si] ;load from arr
;perform operations
;on al here
inc si ;si points to the next array element
loop my_loop
我想知道是否有更好的方法来利用仅一个寄存器,因为 cx 和 si 基本上执行相同的工作(第一个数组元素的偏移量自然源于迭代计数)。
在此示例中,每次迭代时 cx 和 si 的值如下:
cx: [5,4,3,2,1]
si: [array + 0, array + 1, array + 2, array + 3, array + 4]
现在,在每次迭代中,si 的值由公式
si = addr(array) + length - cx
给出,其中 array
和 length
在编译时已知。
在循环内部,这看起来像(这个语法解释了我想要做什么,但很可能是错误的):
mov al, offset(array) + length - cx
我是寻址模式的新手,有没有办法完全避免使用 si 或者你能解释一下为什么不可避免地要使用它吗?
array DB 9,1,4,7,2
length DW 5
和
array
在编译时已知。
length
有一个很好的理由不将 length 定义为基于内存的变量,而是将其定义为等式:
length equ $ - array
。
我想使用
指令循环字节数组。
loop
如果你坚持使用
loop
,那么你将不得不使用额外的寄存器。在 8086 上,CX 寄存器永远不能用于寻址模式。
我是寻址模式的新手,有没有办法完全避免使用 SI 或者你能解释一下为什么不可避免地要使用它吗?
SI 寄存器并非不可避免,因为在 8086 上您可以用 BX、DI 甚至 BP 代替它。 (BP比较特殊,因为它默认使用SS段寄存器,所以不要将其作为您的首选!)
我想知道是否有更好的方法来利用仅一个寄存器
您可以使用单个地址寄存器(BX、SI、DI 或 BP 之一)轻松编写循环。以下是一些方法:
xor bx, bx ; 0
my_loop:
mov al, [array + bx]
...
inc bx ; Increment the 'offset' BX
cmp bx, length ; 5
jb my_loop ; Loop for as long as BX below 5
和:
mov bx, OFFSET array
my_loop:
mov al, [bx]
...
inc bx ; Increment the 'address' BX
cmp bx, OFFSET array + length
jb my_loop ; Loop for as long as BX below (array + 5)
在循环内,我想访问数组中的数据,按顺序(从最低内存地址到最高内存地址)。
这很遗憾,因为如果手头的任务允许的话,你可以反转方向并删除指令:
mov bx, length - 1 ; 5 - 1
my_loop:
mov al, [array + bx]
...
dec bx ; Decrement the 'offset' BX
jns my_loop ; Loop for as long as BX positive [0,4]