What does \'$\' followed by an identifier mean?
x86 assembly, AT&T syntax.
In AT&T syntax $
means to treat what follows as an immediate constant rather than a memory address. In other words,
movl $_start, %eax
loads the address of the symbol _start
into %eax;
movl _start, %eax
reads 4 bytes from memory at the address of _start
into %eax. If you look at the disassembly of both:
0: b8 00 00 00 00 mov $0x0,%eax
1: R_386_32 _start
5: a1 00 00 00 00 mov 0x0,%eax
6: R_386_32 _start
you can see that the only difference is the opcode. The handy, if somewhat self-servingly named, Intel® 64 and IA-32 Architectures Software Developer's Manual (you want volume 2, which is the instruction set reference) says that opcodes B8 through BF encode "load immediate 16/32-bit constant into register" (this is code destined to be loaded into a 32-bit code segment, so it's a 32-bit load; for a 16-bit load, you'd have a "operand size override" prefix byte, 66) and opcode A1 encodes "load 32-bit quantity at specified 32-bit offset from DS (or any other segment, with the appropriate prefix byte) into EAX." With the typical "flat" memory model, that's the moral equivalent of "load 32-bit quantity at specified 32-bit absolute address" but you can see how x86 got its reputation as ridiculously complicated at the machine level.
In case you're wondering, this is what it would look like if we used EBX instead:
a: bb 00 00 00 00 mov $0x0,%ebx
b: R_386_32 _start
f: 8b 1d 00 00 00 00 mov 0x0,%ebx
11: R_386_32 _start
Load-immediate can still be done with a one-byte instruction not counting the operand (it's BB instead of B9, as you might expect it to be, because the internal register order is AX, CX, DX, BX, SP, BP, SI, DI -- seriously) but load-from-absolute-address now has a two-byte instruction, 8B 1D; the second byte is what Intel calls a "ModRM" byte, which specifies both EBX and that an absolute 4-byte address follows.
Generally it means an "immediate" value, ie a number, as opposed to another register value, something retrieved from memory, etc. So, in this case, it's moving the number associated with the symbol _start
into the eax register.