Assembly 为什么我们要在这里取消对标准的引用?
我试图调用Assembly 为什么我们要在这里取消对标准的引用?,assembly,x86,nasm,calling-convention,fputs,Assembly,X86,Nasm,Calling Convention,Fputs,我试图调用fputs(str,stdout)来自程序集 为什么我应该推送dword[stdout]而不是只推送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
fputs(str,stdout)代码>来自程序集
为什么我应该推送dword[stdout]
而不是只推送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
。它是内存中存储文件*
值的静态位置
只有C数组类型的行为类似于asm标签,其中C中的名称是地址,而不是内容
另见
在NASM中,空符号名称是静态地址。在C语言中,一个空名称就是值
(真正的C数组除外,其中裸名称是第一个元素的地址。)
在C中,具有自动存储类(即本地变量)的变量也可以有名称,而不仅仅是静态的。在asm中,符号只能在静态地址上使用。(C中的自动存储通常是x86 asm中的寄存器,如果需要溢出/重新加载,也可以是堆栈空间,如[ebp-8]
。堆栈地址不是链接时间常数,因此不能有标签。您可以相对于ESP或ebp对堆栈进行寻址。)
具有动态存储的对象在C中不能有名称,只能由命名指针指向。因此stdin
的类型是FILE**
,如汇编代码所示,对吗?C库导出的所有全局变量都是这样的吗?@happycoder97:不,这是错误的想法。在NASM中,空符号名是静态地址。在C语言中,不管是自动存储类还是静态存储类,裸名称都是值。(除了true数组,其中裸名称是第一个元素的地址。)(具有动态存储的对象在C中不能有名称,只能由命名指针指向。)