提问人:Umberto Fontanazza 提问时间:11/8/2023 最后编辑:Sep RolandUmberto Fontanazza 更新时间:11/12/2023 访问量:60
8086 - 使用 CX 作为索引的环路阵列
8086 - loop over array using CX as index
问:
我正在使用 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 array
;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 equ $ - array
我想使用指令遍历一个字节数组。
loop
如果您坚持使用 ,那么您将不得不使用额外的寄存器。在 8086 上,CX 寄存器永远不能在寻址模式下使用。loop
我是寻址模式的新手,有没有办法完全避免使用 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)
正如 @ecm 和 @PeterCordes 所建议的那样(删除指令):
mov bx, -length
my_loop:
mov al, [array + length + bx]
...
inc bx ; Increment the 'offset' BX
jnz my_loop ; Loop for as long as BX negative [-5,-1]
在循环中,我想按顺序访问数组中的数据(从最低的内存地址到最高的内存地址)。
这很遗憾(但不是那么多),因为如果手头的任务允许,您可以反转方向并删除指令:
mov bx, length - 1 ; 5 - 1
my_loop:
mov al, [array + bx]
...
dec bx ; Decrement the 'offset' BX
jge my_loop ; Loop for as long as BX positive [0,4]
评论
bx
mov bx, - length
mov al, [array + length + bx]
inc bx
jnz my_loop
mov bx, -length
mov al, [array + length + bx]
inc bx
jnz my_loop
+length
[-4, 0]
mov bx, -(length-1)
mov al, [array+length-1 + bx]
inc bx
jle top
inc
jle
dec bx
jge
dec
jns
dec
jge
dec/jge
loop
dec
jnz
loop
cmp
下一个:遍历范围和更改数据的最快方法
评论