linux - get_pc_thunk 的返回值没有被使用
问题描述
我有这个程序:
static int aux() {
return 1;
}
int _start(){
int a = aux();
return a;
}
当我使用带有标志-nostdlib -m32 -fpie
的 GCC 编译它并生成 ELF 二进制文件时,我得到以下汇编代码:
00001000 <aux>:
1000: f3 0f 1e fb endbr32
1004: 55 push %ebp
1005: 89 e5 mov %esp,%ebp
1007: e8 2d 00 00 00 call 1039 <__x86.get_pc_thunk.ax>
100c: 05 e8 2f 00 00 add $0x2fe8,%eax
1011: b8 01 00 00 00 mov $0x1,%eax
1016: 5d pop %ebp
1017: c3 ret
00001018 <_start>:
1018: f3 0f 1e fb endbr32
101c: 55 push %ebp
101d: 89 e5 mov %esp,%ebp
101f: 83 ec 10 sub $0x10,%esp
1022: e8 12 00 00 00 call 1039 <__x86.get_pc_thunk.ax>
1027: 05 cd 2f 00 00 add $0x2fcd,%eax
102c: e8 cf ff ff ff call 1000 <aux>
1031: 89 45 fc mov %eax,-0x4(%ebp)
1034: 8b 45 fc mov -0x4(%ebp),%eax
1037: c9 leave
1038: c3 ret
00001039 <__x86.get_pc_thunk.ax>:
1039: 8b 04 24 mov (%esp),%eax
103c: c3 ret
我知道该get_pc_thunk
函数用于在 x86 中实现与位置无关的代码,但在这种情况下,我不明白为什么要使用它。我的问题是:
- 该函数返回
eax
寄存器中下一条指令的地址,并且在这两种用法中,都使用一条add
指令来eax
指向 GOT。通常,(至少在访问全局变量时),该eax
寄存器将立即用于访问表中的全局变量。但是,在这种情况下, 将eax
被完全忽略。到底是怎么回事? - 我也不明白为什么
get_pc_thunk
代码中甚至存在,因为两条call
指令都使用相对地址。由于地址是相对的,它们不应该是开箱即用的位置无关的吗?
谢谢!
解决方案
您尚未启用优化,因此 GCC 会发出函数序言,而不考虑它们是否在相关函数中有用。
要查看get_pc_thunk
使用访问全局变量的结果。
删除无用的调用以get_pc_thunk
启用优化,例如通过添加-O2
到 GCC 命令行。
推荐阅读
- amazon-web-services - 使用 AWS CodeBuild 构建 React Native
- mysql - 带有 Hibernate 和 C3P0 的 Mysql 8.0.11:如何禁用通过 SSL 连接?
- angular - 动态绑定到模板引用变量(Angular)
- react-native - 反应本机 IllegalViewOperationException - 尝试删除子计数 0 视图标签上方的视图索引:1
- vba - VBA - 遍历所有工作表并排除一个
- c# - 将多个相同的记录添加到数据库
- entity-framework - 在循环中构建 LINQ 查询
- html - 变换:比例偏移元素
- excel - Excel:基于标准的总和 (SUMIF)
- java - Selenium - 如何在 Java 中正确选择元素?