8086汇编 - 如何访问循环中的数组元素

rar*_*dea 0 memory arrays x86 assembly x86-16

好吧,为了使事情变得尽可能简单,我说我有一个基本循环,我想用它来修改标记为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
Run Code Online (Sandbox Code Playgroud)

我知道我可以通过修改指令al后存储的元素来做到这一点lodsb,然后存储它.但我想知道是否有可能像我上面尝试的那样做.

nrz*_*nrz 5

在x86程序集中,您不能使用存储在内存中的值来间接寻址内存.

您需要读i入一些可用于内存寻址的寄存器,并使用它.您可能需要查看Wikipedia以获取8086内存寻址模式.

所以,替换

mov ds:si[i],1
Run Code Online (Sandbox Code Playgroud)

与(段ds是不必要在这里,因为它是默认的si,bxbx+si太):

xor bx,bx
mov bl,[i]
mov [bx+si],byte 1 ; some other assemblers want byte ptr
Run Code Online (Sandbox Code Playgroud)

您的代码也存在其他问题.整个循环可以更简单,并以这种方式修复:

    lea  si,a

    xor  cx,cx
    mov  cl,[i]

@fill_loop:
    mov  [si], byte 1
    inc  si
    dec  cx
    jnz  @fill_loop
Run Code Online (Sandbox Code Playgroud)

或者,如果要保存1个字节并使用loop指令.

 @fill_loop:
    mov  [si], byte 1
    inc  si
    loop @fill_loop
Run Code Online (Sandbox Code Playgroud)

请注意,在16位模式loop指令中cx,如果cx在递减后不为零,则递减并跳转到标签.但是,在32位模式loop递减ecx和64位模式(x86-64)中,它会递减rcx.