目前我试图更接近汇编程序编程,因此查看了一个简单的hello world程序的汇编程序代码:
#include <stdio.h> int main () { int i; for(i=0; i<10; i++) { printf("Hello,world!\n"); } return 0; }
现在我尝试理解fiew简单汇编程序命令如何工作,同时逐步执行汇编程序代码并分析究竟发生了什么:
0x000000000040052d <+0>: push rbp 0x000000000040052e <+1>: mov rbp,rsp 0x0000000000400531 <+4>: sub rsp,0x10 0x0000000000400535 <+8>: mov DWORD PTR [rbp-0x4],0x0 0x000000000040053c <+15>: jmp 0x40054c <main+31> 0x000000000040053e <+17>: mov edi,0x4005e4 0x0000000000400543 <+22>: call 0x400410 <puts@plt> 0x0000000000400548 <+27>: add DWORD PTR [rbp-0x4],0x1 0x000000000040054c <+31>: cmp DWORD PTR [rbp-0x4],0x9 0x0000000000400550 <+35>: jle 0x40053e <main+17> 0x0000000000400552 <+37>: mov eax,0x0 0x0000000000400557 <+42>: leave 0x0000000000400558 <+43>: ret
问题是我真的不明白这一行:
0x0000000000400543 <+22>: call 0x400410 <puts@plt>
我尝试以各种方式查看地址0x400410,但我真的不明白它真正做到了:/我也不知道这究竟意味着什么:< puts @ plt>
如果有人能帮助我理解这条特定的路线,那真的很棒:)
问候困了
解决方法
PLT表示程序链接表.它是ELF文件中使用的一种特殊技术,用于在可以进行相对寻址的机器上本地化加载时的修复.
您正在调用的函数位于另一个模块(通常是libc.so.x)中,因此在加载程序执行时必须提供函数的实际地址.
PLT本质上是可执行文件(或.so文件)中的一个区域,其中所有未完成的引用都收集在一起.它们具有目标机器的跳转指令的形式,实际地址保持未填充状态.填充地址取决于加载程序.这个过程叫做修复.
因为模块的剩余部分使用相对寻址通过PLT进行函数调用,并且在链接时已知PLT的偏移量,所以不需要修复任何内容.这意味着您的大多数模块可能会继续映射到模块文件而不是交换文件.
还需要注意的是,PLT的补充是GOT,全球抵消表.当PLT用于函数调用时,GOT用于数据.
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。