rares.urdea
rares.urdea

Reputation: 660

8086 assembly - how to access array elements within a loop

Ok, to make things as simple as possible, say I have a basic loop that i want to use in order to modify some elements of an array labeled a. In the following sample code I've tried replacing all elements of a with 1, but that doesn't really work.

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

I am aware that I could simply do this by modifying the element stored in al after the lodsb instruction, and just store that. But I would like to know if it is possible to do something like what I've tried above.

Upvotes: 0

Views: 15439

Answers (2)

nrz
nrz

Reputation: 10580

In x86 assembly you can't use a value stored to a memory to address memory indirectly.

You need to read i into some register that can be used for memory addressing, and use that instead. You may want to check Wikipedia for 8086 memory addressing modes.

So, replace

mov ds:si[i],1

with (segment ds is unnecessary here, as it's the default of si, bx and bx+si too):

xor bx,bx
mov bl,[i]
mov [bx+si],byte 1 ; some other assemblers want byte ptr

There are other problems with your code too. The entire loop can be made easier and fixed this way:

    lea  si,a

    xor  cx,cx
    mov  cl,[i]

@fill_loop:
    mov  [si], byte 1
    inc  si
    dec  cx
    jnz  @fill_loop

Or, if you want to save 1 byte and use loop instruction.

 @fill_loop:
    mov  [si], byte 1
    inc  si
    loop @fill_loop

Note that in 16-bit mode loop instruction decrements cx and jumps to label if cx is not zero after decrement. However, in 32-bit mode loop decrements ecx and in 64-bit mode (x86-64) it decrements rcx.

Upvotes: 6

Andreas Fester
Andreas Fester

Reputation: 36649

I suppose that your code does not even run through the assembler, since

mov ds:si[i],1

is not a valid address mode.

Use something like

mov byte ptr [si],1  ; store value 1 at [SI]
inc si               ; point to next array element

instead (used MASM to verify the syntax).

The DS: prefix is unnecessary for [si] since this is the default.

See also The 80x86 Addressing Modes.

Upvotes: 1

Related Questions