Labels are followed by :
An =
isn't a label, it defines a symbol as an assemble-time constant the way .set
or .equ
does. This is getting the assembler to calculate the length of the string for you, at assemble time.
.
is the current position. Think of .
as an implicit label at the start of this line. You could equivalently have put a str_end:
label after the string and done len = str_end - str
.
Why to use mov str(%rip), %rsi
, when I can use movabs $str, %rsi
?
Those aren't equivalent! mov str(%rip), %rsi
would load 8 bytes from that address, getting the string data into a register. But you need a pointer to the string in a register as an arg for a write(int fd, void *buf, size_t len)
system call. Try it in a debugger and/or strace
and watch it fail.
That's why the movabs
in this code uses $str
, to get the address as a 64-bit immediate.
However, that's the worst way to put a label/symbol address into a register. movabs
with an 8 byte immediate amounts to a 10-byte instruction total, and being absolute it needs runtime fixups in a PIE executable or library (ELF shared object) when the loader chooses an actually base address for the executable.
You actually want LEA str(%rip), %rsi
(7 bytes), or in a non-PIE Linux executable where static addresses fit in the low 31 bits of address space, mov $str, %esi
.