我们可以将局部变量推送到汇编中

时间:2013-06-08 11:44:39

标签: c assembly x86

我制作了一个简单的程序,只需按下一个数字并将其显示在屏幕上即可 不知道出了什么问题

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

以上获取分段错误。

section .data
value db 10

section .text
global main
extern printf
main:
push [value]   
call printf
add esp,4
ret

在第二个版本中,将值变量指向的值推送到堆栈

但是“未指定操作大小”

1 个答案:

答案 0 :(得分:5)

是的,您可以将任何DWORD值(在32位汇编程序中)压入堆栈。

第一个代码片段中的问题是printf期望第一个参数是格式字符串(在C中,你要写printf("%d\n", 10);)。像

这样的东西
 section .data
 fmt db "%d", 10, 0

 ...
 push 10
 push fmt
 call printf
 add esp, 8

会奏效。

在第二个代码片段中,您应该编写push [value]而不是push dword [value],但如果您的value变量是单个字节,那么这是不正确的。将其声明为DWORD(dd),或执行

movsx eax, byte [value] ; if it's a signed integer; movzx for unsigned
push eax

还有一件事。调用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