2013-02-20 87 views
0

好的,爲了使事情儘可能簡單,說我有一個基本的循環,我想用來修改標記爲a的數組的一些元素。在下面的示例代碼中,我嘗試用1替換1的所有元素,但這並不起作用。8086程序集 - 如何訪問循環內的數組元素

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 

我知道我可以簡單地通過修改存儲在allodsb指令之後的元素做到這一點,只是存儲。但我想知道是否有可能做到像我上面嘗試過的那樣。

回答

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

'mov bx,[i]'如果'i'是一個字節就不會組裝或工作正常。你用'movzx'弄明白了。但知道這是80386+指令可能很重要。 – 2013-02-20 13:09:31

+0

@AlexeyFrunze你是對的,所以我修復它並轉換爲8088/8086代碼。 – nrz 2013-02-20 13:12:00

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