Search code examples
assemblyx86x86-16gnu-assembler

Why is it necessary to use '$' sign in AT & T assembly?


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


Solution

  • $ 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.