I am new to assembly language. I recently stepped into something miserable. I created a sample assembly program as follows:
head.h
#define _Length_ 0x0A
main.S
movw $_LENGTH_, %ax
movw _LENGTH_, %ax
Now what is the difference between the two MOV statements? What will be the value of ax?
I am using Ubuntu and GAS assembler(AT & T syntax).
Thanks in advance
$
and %
decorators in AT&T syntax makes it simpler to parse (for the assembler, not necessarily for humans).
I'm going to pretend that you actually wrote #define _LENGTH_ 0x0A
instead of #define _Length_ 0x0A
.
If not, then _LENGTH_
is treated as an external symbol by the assembler, and _Length_
is a macro you defined that never gets substituted anywhere, so the assembler never knows it exists. The C preprocessor is totally separate from the assembler, just like in C.
$
always means an immediate constant. So movw $0x0A, %ax
puts 0xA into AX.
A number or symbol without a $
as an operand always means a memory operand. movw 0x0A, %ax
is a load from address [ds:0xA]
into AX (using NASM notation for an effective address). This is almost never what you want.
movw $undefined_symbol, %ax
will assemble (use objdump -drwC
to see the relocation info in the .o
), but fail at link time.