我在一些汇编语言的书中发现他们很乐意将fprintf
与stdout
一起使用。他们只是将stdout
作为一个已知符号引用。我试图在我的代码中这样做,并且链接器抱怨找不到stdout。我尝试了包括前导下划线在内的拼写变体。我还反汇编了printf
。它使用以下代码行设置对vfprintf
的调用:
leaq 0x41879948(%rip), %rax ; __stdoutp
因此,我似乎应该能够做一些类似的事情:
leaq __stdoutp(%rip), %rdi
不起作用。链接器抱怨未定义的符号。尝试使用变体。省略了p后缀、一个或两个下划线。没有任何效果。
有什么想法,或者内幕消息,我可以遵循访问这个符号?
1条答案
按热度按时间ve7v8dk21#
基于@PeterCordes的建议,着眼于编译器生成的asm,我编写了一个c程序:
我对它运行了
clang -S main.c
,并查看了asm。结果表明,这在ABI(第3.5.4节)中有规定
与位置无关的代码不能包含绝对地址。要访问 * 全局符号 *,必须从全局偏移量表加载符号的地址。GOT中条目的地址可以通过小模型中的%rip-relative指令获得。
c代码中的
stdout
指的是__stdoutp
符号。因为macosx,它在汇编程序中变成了___stdoutp
。类似于main
是_main
。ABI第5.2节以这种方式解释了GOT
全局偏移表在私有数据中保存绝对地址,因此在不损害程序文本的位置独立性和可共享性的情况下使地址可用。