Search code examples
assemblyx86nasmaddressing

Nasm how to access dds and dws under a specific label?


Considering the following label:

foo:
    dw 0
    dd 0

Now how can one access the double word or dd(word?) under the foo label from another label?

bar: ;Subroutine
    mov eax, [foo] ;Now how can I move the value stored in foo's dw into eax for example?
                   ;I assume this isn't the correct way?
    add eax, 01h   ;Do something with the value
    mov [foo], eax ;Store it back into foo's dw
    ret

I am aware that there may be answers to this in documentations etc. but I'm lacking the proper terminology to find any good results using Google.


Solution

  • dw declares a word, which on x86 platforms is 16 bits. The size of eax is 32 bits (a doubleword). Hence, using mov eax,[foo] would usually be a bad idea.

    Imagine that you have the following:

    foo: dw 0x1122
         dd 0x33445566
    

    What you'd get in eax if you did mov eax,[foo] is 0x55661122. The CPU just reads whatever it finds at the given address as if it was a doubleword (so long as you don't try to access data not allocated to your program), without caring about what that data might be.

    If you want to get just 0x1122 you could read it into ax (the low word of eax): mov ax,[foo]. Note that the upper word of eax will remain unchanged.

    If you want to get 0x1122 into eax you should use the zero-extending variant of mov: movzx eax,word [foo]. This will read just the first word located at foo, zero-extend it into a doubleword, and place the result in eax.

    If you wanted to read the doubleword you've declared (0x33445566 in my example), you would use mov eax,[foo+2].