为什么我们必须在这里取消引用标准输出?

Why do we have to dereference stdout here?

我正在尝试从程序集调用 fputs(str, stdout);

为什么我应该 push dword [stdout] 而不是 push stdout

既然在 C 中我们不做 fputs(str, *stdout),为什么我们需要在汇编中取消引用 stdout

完整代码:

extern fputs
extern stdout

section .data
    hw: db "Hello World!", 10, 0

section .text
    global main

main:
    enter 0,0

    push dword [stdout]
    ;push stdout
    push hw
    call fputs

    leave
    mov eax, 0
    ret

您正在取消引用 asm 标签 stdout,它相当于 C 中的 &stdout。它是内存中的静态位置,FILE* value 已存储。

只有 C 数组类型的行为类似于 asm 标签,其中 C 中的名称是地址,而不是内容。

另见 Why in NASM do we have to use square brackets ([ ]) to MOV to memory location?


在NASM中,裸符号名就是静态地址。在 C 中,裸名是值 .

(真正的 C 数组除外,其中裸名是第一个元素的地址。)


在C中,自动存储的变量class(即局部变量)也可以有名字,而不仅仅是静态的。在 asm 中,符号只能放在静态地址上。 (C 中的自动存储通常是 x86 asm 中的寄存器,或者堆栈 space,如 [ebp - 8],如果你需要 spill/reload。堆栈地址不是 link-时间常数,所以不能有标签。你相对于 ESP 或 EBP 寻址堆栈。)

具有动态存储的对象在 C 中不能有名称,只能由命名指针指向。