好的,为了让事情变得尽可能简单,我说我想要使用一个基本循环来修改标记为a的数组的某些元素。在下面的示例代码中,我尝试将a的所有元素替换为1,但这确实不起作用。
assume cs:code ,ds:data
data segment
a db 1,2,3,4
i db 0
data ends
code segment
start:
mov ax,data
mov ds,ax
lea si,a
the_loop:
mov cl,i
cmp cl,4
jae the_end
mov ds:si[i],1 ; this is the part that i don't really understand since
inc i ; i'm expecting i=0 and ds:si[i] equiv to ds:si[0] which
loop the_loop ; is apparently not the case here since i actually receives the
; the value 1
the_end:
mov ax,4c00h
int 21h
code ends
end start
我知道我可以通过在al
指令之后修改存储在lodsb
中的元素来执行此操作,并将其存储起来。但我想知道是否可以做一些我上面尝试过的事情。
答案 0 :(得分:5)
在x86程序集中,您不能使用存储在内存中的值来间接寻址内存。
您需要将i
读入一些可用于内存寻址的寄存器,并使用它。您可以查看Wikipedia for 8086 memory addressing modes。
所以,替换
mov ds:si[i],1
这里不需要(段ds
),因为它是si
,bx
和bx+si
的默认值:
xor bx,bx
mov bl,[i]
mov [bx+si],byte 1 ; some other assemblers want byte ptr
您的代码也存在其他问题。整个循环可以更简单,并以这种方式修复:
lea si,a
xor cx,cx
mov cl,[i]
@fill_loop:
mov [si], byte 1
inc si
dec cx
jnz @fill_loop
或者,如果您想保存1个字节并使用loop
指令。
@fill_loop:
mov [si], byte 1
inc si
loop @fill_loop
请注意,在16位模式下loop
指令递减cx
并在递减后cx
不为零时跳转到标签。但是,在32位模式loop
递减ecx
并且在64位模式(x86-64)中,它递减rcx
。
答案 1 :(得分:1)
我认为你的代码甚至没有通过汇编程序运行,因为
mov ds:si[i],1
不是有效的地址模式。
使用类似
的内容mov byte ptr [si],1 ; store value 1 at [SI]
inc si ; point to next array element
(使用MASM验证语法)。
DS:
不需要[si]
前缀,因为这是默认值。