PIC的组装 [英] Assembly of PIC
问题描述
地址 STR
存储堆栈(可以使用弹出
来获取它,和它的位置无关)
The address of str
is stored the stack(can use pop
to fetch it, and it's position independent):
.text
str:
.string "test\n"
但现在 STR
的地址不在堆栈(不能使用弹出
来取水的时候,但 STR(%RIP)
(RIP相对寻址)是PIC):
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
这是我从我的previous发现的问题,
This is what I found from my previous question,
但我不明白汇编如何决定 STR
的地址应该是在栈或没有?
but I don't understand how assembler decides address of str
should be in the stack or not?
当我应该使用RIP-相对寻址,或使用弹出
使其PIC?
WHen should I use RIP-relative addressing ,or use pop
to make it PIC?
更新
这是工作:
.text
call start
str:
.string "test\n"
start:
movq $1, %rax
movq $1, %rdi
popq %rsi
movq $5, %rdx
syscall
ret
但是,如果我更改 popq%RSI
到 LEA STR(%RIP),%RSI
,它wlll引起段错误...
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 that
x: call start
y:
在道德上是等同于(忽略我们垃圾%RAX
这里):
x: lea y(%rip), %rax
push %rax
jmp start
y:
相反 RET
从堆栈中弹出一个地址并跳转到它。
Conversely RET
pops an address from the stack and jumps to it.
现在在你的code你做 popq%RSI
再后来 RET
跳回什么叫您。如果你的只是的修改 popq
到 LEA STR(%RIP),%RSI
来负载%RSI
与 STR
你仍然有返回值(地址的地址海峡
在堆栈中)!要解决您的code只需手动弹出返回值从堆栈(加$ 8%RSP
)以上三立移动 STR
来后的功能,所以你不需要笨拙的呼叫。
Now in your code you do popq %rsi
and then later ret
jumps back to whatever called you. If you just change the popq
to lea str(%rip), %rsi
to load %rsi
with the address of str
you still have the return value (address of str
) on the stack! To fix your code simply manually pop the return value off the stack (add $8, %rsp
) OR more sanely move str
to after the function so you don't need the awkward call.
更新完全独立例如:
# p.s
#
# Compile using:
# gcc -c -fPIC -o p.o p.s
# gcc -fPIC -nostdlib -o p -Wl,-estart p.o
.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"
拆卸code。与 objdump的-dp
显示,code确实位置无关,即使使用。数据<当/ code>。
Disassembling the code with objdump -d p
reveals that the code is indeed 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
这篇关于PIC的组装的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!