我正在尝试从程序集调用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
答案 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语言中不能具有名称,只能由已命名的指针指向。