The address of str
is stored the stack(can use pop
to fetch it, and it's position independent):
.text
str:
.string "test\n"
But now the address of str
is not in the stack(can't use pop
to fetch it, but str(%rip)
(RIP relative addressing) is PIC):
.text
str:
.skip 64
This is what I found from my previous question,
but I don't understand how assembler decides address of str
should be in the stack or not?
WHen should I use RIP-relative addressing ,or use pop
to make it PIC?
UPDATE
This is working:
.text
call start
str:
.string "test\n"
start:
movq $1, %rax
movq $1, %rdi
popq %rsi
movq $5, %rdx
syscall
ret
But if I change popq %rsi
to lea str(%rip),%rsi
,it wlll cause segmentation fault...
Just to be completely clear: the
CALL
instruction pushes the address of the instruction following it onto the stack and jumps to the target address. This means thatis morally equivalent to (ignoring that we trash
%rax
here):Conversely
RET
pops an address from the stack and jumps to it.Now in your code you do
popq %rsi
and then laterret
jumps back to whatever called you. If you just change thepopq
tolea str(%rip), %rsi
to load%rsi
with the address ofstr
you still have the return value (address ofstr
) on the stack! To fix your code simply manually pop the return value off the stack (add $8, %rsp
) OR more sanely movestr
to after the function so you don't need the awkward call.Updated with complete stand alone example:
Disassembling the code with
objdump -d p
reveals that the code is indeed position independent, even when using.data
.