我正在学习x86上的汇编并尝试理解一个将添加两个数字的程序。
这段代码并在其上做了一些修改,以便更好地理解它。
section .data
message1 db "value=%d%d",10,0
message db "value=%d",10,0
section .text
global main
extern printf
main:
mov eax, 55
mov ebx, 45
add eax,ebx
push eax
push ebx
push message1
call printf
add esp, 16
mov eax ,[esp] // it will move value pointed by esb to eax
push eax
push message
call printf
add esp, 12
ret
我期待输出值= 45100,值= 55但是它的值是= 45100 .value = 1
昨天我问过SO的问题我从哪里知道call printf也将地址推送到堆栈
答案 0 :(得分:1)
您的代码中存在两个问题。首先,你永远不会把55推到堆栈上,因为eax
是45 + 55之前你推。它
其次,您的堆栈指针算法已关闭。在调用esp
之前尝试将eax
恢复为其值之前,您向printf
添加了太多内容。
从您的call printf
返回时,您的堆栈框架如下所示:
+-------
| .....
+-------
| .....
+-------
| 100
+-------
| 45
+-------
esp| message1
+--------
然后你add esp, 16
,结果
+-------
esp | .....
+-------
| .....
+-------
| 100
+-------
| 45
+-------
| message1
+--------
现在,当您将eax
设置为[esp]
时,您会被两个单词关闭。
我相信这会给出正确的行为:
main:
mov eax, 55
push eax // save eax on the stack
mov ebx, 45
add eax,ebx
push eax
push ebx
push message1
call printf
add esp, 12 // remove parameters from stack
mov eax ,[esp] // stored eax (55) is now at top of stack
push eax
push message
call printf
add esp, 12 // remove parameters and stored eax from stack
ret