Pic assembly

The str address is stored on the stack (you can use pop to retrieve it, and it does not depend on the position):

 .text str: .string "test\n" 

But now the str address is not on the stack (cannot use pop to retrieve it, but str(%rip) (relative RIP addressing) is PIC):

 .text str: .skip 64 

This is what I found from my previous question,

but I don’t understand how the assembler solves the address str should be on the stack or not?

In which case should I use RIP relative addressing or use pop to do this PIC?

UPDATE

It works:

 .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 , this will result in a segmentation error ...

+2
source share
1 answer

Just to be completely clear: the CALL command pushes the address of the instruction following it onto the stack and jumps to the target address. It means that

 x: call start y: 

morally equivalent (ignoring the fact that we are rubbish %rax ):

 x: lea y(%rip), %rax push %rax jmp start y: 

Conversely, RET pops the address from the stack and jumps to it.

Now in your code you make popq %rsi and then RET jump back to what you call. If you just changed popq to lea str(%rip), %rsi to load %rsi with str address, you still have the return value ( str address) on the stack! To fix your code, simply manually pull the return value from the stack ( add $8, %rsp ) or more safely move str after the function so you don't need an inconvenient call.

Updated with full standalone example:

 # ps # # Compile using: # gcc -c -fPIC -o po ps # gcc -fPIC -nostdlib -op -Wl,-estart po .text .global start # So we can use it as an entry point start: movq $1, %rax #sys_write movq $1, %rdi lea str(%rip), %rsi movq $5, %rdx syscall mov $60, %rax #sys_exit mov $0, %rdi syscall .data str: .string "test\n" 

Parsing the code with objdump -dp shows that the code is really position-independent, even when using .data .

 p: file format elf64-x86-64 Disassembly of section .text: 000000000040010c <start>: 40010c: 48 c7 c0 01 00 00 00 mov $0x1,%rax 400113: 48 c7 c7 01 00 00 00 mov $0x1,%rdi 40011a: 48 8d 35 1b 00 20 00 lea 0x20001b(%rip),%rsi # 60013c <str> 400121: 48 c7 c2 05 00 00 00 mov $0x5,%rdx 400128: 0f 05 syscall 40012a: 48 c7 c0 3c 00 00 00 mov $0x3c,%rax 400131: 48 c7 c7 00 00 00 00 mov $0x0,%rdi 400138: 0f 05 syscall 
+1
source

All Articles