I am trying to get to grips with MASM32 and am confused by the following:
I thought that brackets were used for indirection so if I have the a pre-defined variable
.data
item dd 42
then
mov ebx, item
would put the contents of 'item', i.e. the number 42, into ebx and
mov ebx, [item]
would put the address of 'item', i.e. where the 42 is stored, into ebx.
But the following code in a console app:
mov ebx, item
invoke dwtoa, ebx, ADDR valuestr
invoke StdOut, ADDR valuestr
mov ebx, [item]
invoke dwtoa, ebx, ADDR valuestr
invoke StdOut, ADDR valuestr
prints 42 twice. To get the address of 'item' I seem to need
mov ebx, [OFFSET item]
invoke dwtoa, ebx, ADDR valuestr
invoke StdOut, ADDR valuestr
Can anybody explain what square brackets are for in MASM, or point me at a good reference.
The brackets mean to de-reference an address. For example mov eax, [1234] means, mov the contents of address 1234 to EAX. So: 1234 00001. EAX will contain 00001.
Square brackets means 'the variable at the memory address stored in RAX”. So: mov RAX, 12. means “store value 12 into RAX” mov [RAX], 12. means “store value 12 in the memory cell whose address is stored in RAX'
The parentheses indicate the move instruction should consider the value in rbp to be a memory address, that it should move the value 42 to the memory address referenced by rbp (or actually to the memory address four bytes before the value of rbp ) and not into rbp itself.
MASM is unusual for an assembly language in that is has types. MASM knows because of how you defined the symbol item
that is a memory location of type DWORD
. When you use it as an operand knows that you (probably) mean that you want the value stored at the address, not the value of the address. So it doesn't matter if you use item
or [item]
MASM assumes you mean the later. If you really want the address of item instead you need to use OFFSET item
.
On the other hand if you had defined item
as constant using item = 42
then mov ebx, item
would load the immediate value. Because of this ambiguity, you need to know how item
was defined to determine if it's an immediate operand or a memory operand, it's good idea to avoid using a bare symbol as an operand.
I should add that the square brackets []
mean pretty much nothing to MASM when you're just using symbols or numbers. They only mean something when you use them with registers. Here's some examples:
item DD 42
const = 43
mov eax, item ; memory operand (the value stored at item)
mov eax, [item] ; memory operand
mov eax, OFFSET item ; immediate operand (the address of item)
mov eax, [OFFSET item] ; immediate operand
mov eax, const ; immediate operand (43)
mov eax, [const] ; immediate operand
mov eax, ds:[const] ; memory operand (the value at address 43)
mov eax, fs:30h ; memory operand (the value at address 30h + fs base)
mov eax, OFFSET const ; immediate operand
mov eax, [OFFSET const] ; immediate operand
mov eax, 42 ; immediate operand
mov eax, ebx ; register operand (the value of EBX)
mov eax, [ebx] ; indirect operand (the value pointed to by EBX)
So without registers square brackets only show your intent. You should put square brackets around symbols if you intend to use them as memory operands, and use OFFSET
with symbols you intend to use as immediate values.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With