PIC的组装 [英] Assembly of PIC

查看:208
本文介绍了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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆