assembly 我如何从mac上的汇编中获得对标准输入的引用?

t98cgbkg  于 2022-11-13  发布在  Mac
关注(0)|答案(1)|浏览(141)

我在一些汇编语言的书中发现他们很乐意将fprintfstdout一起使用。他们只是将stdout作为一个已知符号引用。我试图在我的代码中这样做,并且链接器抱怨找不到stdout。我尝试了包括前导下划线在内的拼写变体。我还反汇编了printf。它使用以下代码行设置对vfprintf的调用:

leaq   0x41879948(%rip), %rax    ; __stdoutp

因此,我似乎应该能够做一些类似的事情:

leaq __stdoutp(%rip), %rdi

不起作用。链接器抱怨未定义的符号。尝试使用变体。省略了p后缀、一个或两个下划线。没有任何效果。
有什么想法,或者内幕消息,我可以遵循访问这个符号?

ve7v8dk2

ve7v8dk21#

基于@PeterCordes的建议,着眼于编译器生成的asm,我编写了一个c程序:

#include <stdio.h>
int main() { fprintf(stdout, "Hello, world!\n"); }

我对它运行了clang -S main.c,并查看了asm。

movq    ___stdoutp@GOTPCREL(%rip), %rax
    movq    (%rax), %rdi

结果表明,这在ABI(第3.5.4节)中有规定
与位置无关的代码不能包含绝对地址。要访问 * 全局符号 *,必须从全局偏移量表加载符号的地址。GOT中条目的地址可以通过小模型中的%rip-relative指令获得。
c代码中的stdout指的是__stdoutp符号。因为macosx,它在汇编程序中变成了___stdoutp。类似于main_main
ABI第5.2节以这种方式解释了GOT
全局偏移表在私有数据中保存绝对地址,因此在不损害程序文本的位置独立性和可共享性的情况下使地址可用。

相关问题