Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/assembly/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Assembly 为什么esp在推入此x86汇编代码后向下移动0xC?_Assembly_X86_Fasm - Fatal编程技术网

Assembly 为什么esp在推入此x86汇编代码后向下移动0xC?

Assembly 为什么esp在推入此x86汇编代码后向下移动0xC?,assembly,x86,fasm,Assembly,X86,Fasm,我写了这个小程序来测量电除尘器在一次推力后减少了多少。整个程序不在此处,但相关部分为: format PE console entry main include 'macro/import32.inc' section '.data' data readable writeable msg db "The esp address is: %.8X\n", 0 p db "pause>nul", 0 some_num dd 0 section '.code' code readable

我写了这个小程序来测量电除尘器在一次推力后减少了多少。整个程序不在此处,但相关部分为:

format PE console
entry main
include 'macro/import32.inc'

section '.data' data readable writeable
msg db "The esp address is: %.8X\n", 0
p db "pause>nul", 0
some_num dd 0

section '.code' code readable executable

main:
mov eax, esp
push ebp ; store caller's base ptr
mov ebp, esp ; Set this func's base ptr
push eax
push msg
call [printf]
push esp
push msg
call [printf]

打印到控制台的两个地址彼此相差0xC,而不是x86 push指令中所说的4。

Michael Petch的评论让我理解了这个问题的答案。问题是,我必须使用push指令来调用printf,这导致esp额外递减几次。下面的代码实现了这一目标,因为它在第一次printf之后清理堆栈,并使用eax将esp保存在正确的状态:

format PE console
entry main
include 'macro/import32.inc'

section '.data' data readable writeable
msg db "The number is: %.8X\n", 0
p db "pause>nul", 0
some_num dd 0

section '.code' code readable executable

main:
mov eax, esp
push ebp ; store caller's base ptr
mov ebp, esp ; Set this func's base ptr
push eax
push msg
call [printf]
add esp, 8
mov eax, esp
push eax
push msg
call [printf]

通过使用add esp,8,我们适当地释放了对printf的第一次调用的两次推送的堆栈,这样esp就回到了要测量的原始位置。然后,我们立即将esp保存在eax中,以便以下推操作不会干扰测量状态。结果证实push确实从esp中减去了4。

,因为在每次printf调用之后都没有清理堆栈。如果为printf打开2个4字节的参数8 total0,则必须在add esp,8之后添加8字节。由于每次调用后都不进行清理,所以您会继续将数据推送到堆栈中,而不会删除旧数据。@MichaelPetch噢,Michael,谢谢您,先生。。。总n00b装配错误。啊,好吧,你生活和学习。我忽略了将对prinft的推送视为推送,并意识到它们已被分解到数学中。推送esp在esp-=4发生之前推送该值,因此mov eax、esp/push eax可以简化为在没有堆栈操作的情况下推送esp。