我正在尝试打电话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
您正在取消引用 asm 标签stdout
,这相当于&stdout
在 C 中。它是内存中的静态位置FILE*
value被储存了。
只有 C 数组类型的行为类似于 asm 标签,其中 C 中的名称是地址,而不是内容。
也可以看看为什么在 NASM 中我们必须使用方括号 ([ ]) 来 MOV 到内存位置? https://stackoverflow.com/questions/49534661/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 中不能有名称,只能通过命名指针来指向。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)