在汇编 Intel x64 中为什么要在 stdin 周围放置方括号

In assembly Intel x64 why should place square brackets around stdin

今天在汇编中调用 fgets 进行练习。 为了将 FILE* 传递到文件流,我写了 mov rdx, [stdin].

但是为什么要放在方括号里?因为我不需要那个指针的值,只需要指针本身。应该提一下,那个 lea rdx, [stdin] 也不起作用。我记得,它导致 SIGSEGV 被发送到程序。

据我所知,mov 指令的操作数中的方括号与 C 中的取消引用指针的含义相同。我还知道 libc 在运行时动态链接到我的可执行文件,并映射到程序的堆栈和堆之间的某个位置虚拟内存地址 space.

YASM,glibc,Linux x64.

FILE *stdin;是指针类型的全局变量。这意味着存储在静态位置的值是您想要的指针。由于我们要传递的是一个指针,存储在标有stdin的位置,我们需要从[stdin]加载,而不是传递[的地址=12=] 符号.

如果声明为 FILE stdin 并在 C 中用作 fgets(buf, size, &stdin).[=23=,则传递 stdin(使用 lea rdx, [rel stdin])的地址将起作用]


libc 的定义 FILE *stdin; 等价于这个 asm.

section .data
stdin: dq  stdin_FILE_struct           ; This is a pointer stored in memory

section .bss
...
stdin_FILE_struct:           ;; TOTALLY MADE UP, it's not actually like this
    resq 1                       ; something
    resd 1                       ; something_else
    resb 4096                    ; buffer

stdin可能实际上在BSS中,它指向的数据很可能是由glibc init函数动态分配的。

stdin 是一个不透明的指针。您不需要关心它指向什么,只需要它包含一个指向实际 FILE 对象的指针,这就是您需要传递给 fgets 的内容。