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

问题描述 投票:1回答:1

我试图从汇编中调用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
assembly x86 nasm calling-convention fputs
1个回答
4
投票

你要取消引用asm标签stdout,它相当于C中的&stdout。它是内存中存储FILE*值的静态位置。

只有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中具有名称,只能由命名指针指向。

© www.soinside.com 2019 - 2024. All rights reserved.