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

时间:2019-04-03 13:25:02

标签: assembly x86 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

1 个答案:

答案 0 :(得分:4)

您要取消引用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语言中,具有自动存储功能的变量也可以具有名称,而不仅仅是静态名称。在asm中,符号只能在静态地址上使用。 (C中的自动存储通常是x86 asm中的寄存器,如果需要溢出/重装,则为[ebp - 8]之类的堆栈空间。堆栈地址不是链接时常数,因此不能有标签。相对于ESP或EBP的堆栈。)

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