我制作了一个简单的程序,只需按下一个数字并将其显示在屏幕上,但不知道出了什么问题
section .data
value db 10
section .text
global main
extern printf
main:
push 10 //can we push value directly on stack?
call printf
add esp,4
ret
Run Code Online (Sandbox Code Playgroud)
以上获取分段错误.
section .data
value db 10
section .text
global main
extern printf
main:
push [value]
call printf
add esp,4
ret
Run Code Online (Sandbox Code Playgroud)
在第二个版本中,将值变量指向的值推送到堆栈
但是"未指定操作大小"
是的,您可以将任何DWORD值(在32位汇编程序中)推送到堆栈上.
第一个代码片段中的问题是printf期望第一个参数是格式字符串(在C中,你要编写printf("%d\n", 10);).所以像
section .data
fmt db "%d", 10, 0
...
push 10
push fmt
call printf
add esp, 8
Run Code Online (Sandbox Code Playgroud)
将工作.
在第二个代码片段中,而不是push [value]你应该写push dword [value],但如果你的value变量是一个字节,这是不正确的.将其声明为DWORD(dd)或执行
movsx eax, byte [value] ; if it's a signed integer; movzx for unsigned
push eax
Run Code Online (Sandbox Code Playgroud)
还有一件事.调用printf(或任何C库函数)时,请注意堆栈对齐.某些平台要求在函数调用时堆栈是16字节对齐的(这对于正确执行优化的CPU指令(如SSE)是必需的).因此,要使堆栈对齐:
push ebp
mov ebp, esp
sub esp, 8 ; reserve 8 bytes for parameters
and esp, -16 ; align the stack (the reserved space can increase)
mov dword [esp], fmt ; put parameters into stack
mov dword [esp+4], 10
call printf
mov esp, ebp ; restore stack
pop ebp
Run Code Online (Sandbox Code Playgroud)