1

im new to assembly and im trying to iterate through an array and find the sum as i go along and put the sum into eax. This is my code so far.

.data
    myArray db 1, 2, 3



.code
main PROC

    mov eax, 3      
    mov ebx, 0              
    mov esi, OFFSET myArray     

top: add ebx, [esi]

    add ecx, 1              
    dec eax                 
    jnz top                 

done:
    mov eax, ebx
    INVOKE ExitProcess, 0

Im pretty sure im using the OFFSET wrong. When i debug the program ebx is still 0 even though ive added [esi] to it. Like i said im pretty sure im using offset wrong but any tips on how to fix it so the [esi] is added to ebx with each iteration. Registers when i have a breakpoint at mov eax, ebx: EAX = 00000000 EBX = 00090603 ECX = 009B1008 EDX = 009B1005 ESI = 009B4000 EDI = 009B1005 EIP = 009B1025 ESP = 0082FE18 EBP = 0082FE24 EFL = 00000246

1 Answer 1

3

For a MASM-style assembler, your use of OFFSET is fine, but

  • The loop forgets to advance the pointer to the next array element! Perhaps add ecx, 1 was meant to be add esi, 1?
  • The add ebx, [esi] instruction will add a whole dword to EBX.
    Because myArray comprised bytes, you need to extend the values

Both errors explain why the dump shows EBX = 00090603 in the end (00030201h + 00030201h + 00030201h = 00090603h).

  xor   eax, eax            ; Sum
  mov   ecx, 3
  mov   esi, OFFSET myArray
More:
  movzx edx, byte ptr [esi]
  inc   esi                 ; Move to next byte
  add   eax, edx            ; Sum += Item
  dec   ecx
  jnz   More

Since in the end you want the result in EAX anyway, then also add to EAX instead of to EBX in the loop.

Data directives db, dw, dd

When you define an array of bytes using the db directive as in myArray db 1, 2, 3 the memory at the address myArray will show next 3 bytes:

1, 2, 3

To fetch a single array element and have it stored in a 32-bit register you would use movzx edx, byte ptr [esi] which is an instruction that reads 1 byte from memory, extends the byte into a dword padded with zeroes on the left1, and then leaves the result in the 32-bit register.

When you define an array of words using the dw directive as in myArray dw 1, 2, 3 the memory at the address myArray will show next 6 bytes:

1, 0, 2, 0, 3, 0

To fetch a single array element and have it stored in a 32-bit register you would use movzx edx, word ptr [esi] which is an instruction that reads 2 bytes (aka word) from memory, extends the word into a dword padded with zeroes on the left1, and then leaves the result in the 32-bit register.

When you define an array of dwords using the dd directive as in myArray dd 1, 2, 3 the memory at the address myArray will show next 12 bytes:

1, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0

To fetch a single array element and have it stored in a 32-bit register you would use mov edx, [esi] which is an instruction that reads 4 bytes (aka dword) from memory, and then leaves the result in the 32-bit register.

1 Although in the register the zeroes are padded on the left, in memory the zeroes are padded on the right since x86 is a little-endian architecture. The low byte(s) come(s) before the high byte(s) when seen in memory.

EDX = 00000001h   myArray : 1, 0, 0, 0
Sign up to request clarification or add additional context in comments.

2 Comments

I tried what you suggested but i get 2 errors when i debug: MSB3721: The command 'command' exited with code 1 and A2009 syntax error expression on line 18. Do you know why these arise and how to fix them
@RobbieWoodhams Read the edit to my answer. MASM requires byte ptr instead of byte.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.