为什么我们必须在这里取消引用stdout?

hap*_*r97 1 x86 assembly nasm calling-convention fputs

我正试图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
Run Code Online (Sandbox Code Playgroud)

Pet*_*des 6

您正在取消引用asm标签stdout,该标签与&stdoutC中的等效。它是内存中存储FILE* 的静态位置。

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

另请参见为什么在NASM中我们必须使用方括号([])将MOV移至内存位置?


在NASM中,裸符号名称是静态地址。在C中,裸名是value

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


在C语言中,具有自动存储类的变量(即本地var)也可以具有名称,而不仅仅是静态的。在asm中,符号只能在静态地址上使用。(C中的自动存储通常是x86 asm中的寄存器,或者是堆栈空间,例如[ebp - 8]您是否需要溢出/重新加载。堆栈地址不是链接时常数,因此不能有标签。您可以相对于ESP或EBP。)

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