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

时间:2013-02-20 12:32:48

标签: arrays memory assembly x86 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

我知道我可以通过在al指令之后修改存储在lodsb中的元素来执行此操作,并将其存储起来。但我想知道是否可以做一些我上面尝试过的事情。

2 个答案:

答案 0 :(得分:5)

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

您需要将i读入一些可用于内存寻址的寄存器,并使用它。您可以查看Wikipedia for 8086 memory addressing modes

所以,替换

mov ds:si[i],1
这里不需要

(段ds),因为它是sibxbx+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]前缀,因为这是默认值。

另见The 80x86 Addressing Modes