I'm studying x86-64 assembly and for code to store a strings in a char* array;
char *name[2];
name[0] = "Name";
name[1] = "null";
here's the assembly generated by the compiler (function prologue immediately precedes this):
mov %fs:0x28,%rax
mov %rax,-0x8(%rbp)
xor %eax,%eax
lea 0x9689d(%rip),%rax
mov %rax,-0x20(%rbp)
lea 0x9689a(%rip),%rax
mov %rax,-0x18(%rbp)
To the best of my knowledge, I believe this copies the address of the supposed string into the rax
register and then into the address space at an 8-byte negative offset from the rbp
register.
The next three instructions, however, I'm lost out on. I believe the xor %eax,%eax
instruction, stores the value 0
in the eax
register.
I'm not sure exactly what the lea 0x9689d(%rip),%rax
and lea 0x9689a(%rip),%rax
instructions are supposed to do. My guess is, copy the address stored in the rip
(64-bit instruction pointer) register to the rax
register? (with it's lower 32-bits now zero, thanks to the xor
instruction?).
First question
Am I right or wrong with that assumption? And why the compiler chose those instructions?
(Recall, rax
register held the address to the string)
Second question
And why didn't the compiler just copy the addresses of the string like it did in the first instruction %fs:0x28,%rax
?
Third question
As local variables, the first string's address was stored at a negative 8-byte offset from the rbp
. Why is the second string stored at offset of negative 24-bytes (16 bytes away from the first string instead of just 8), and I'm guessing '/0'
character stored at offset of negative 32-bytes?