目前,我正在阅读Karen Miller撰写的“使用英特尔奔腾计算机架构的汇编语言介绍”一书。
首先,给出调用和 ret 的解释,它解释了返回地址的保存。 其次,解释了叶子和非叶子过程之间的区别:叶子过程不会调用任何其他东西,而非叶子过程会这样做。这使得1个双字(32位)空间用于堆栈帧的其余部分:
此返回地址被视为该过程框架的一部分。帧内的第一个双字是返回地址。对于非叶子过程,为帧的其余部分分配的空间量是一个小于帧大小的双字,因为调用指令为返回地址分配(和使用)空间
之后,给出了一个代码示例,它将我带到了我的主要问题。
A: sub ESP, 20 ; allocate frame for A
; return address is at [ESP+20] in A's frame
call B
call C
add ESP, 20 ; deallocate A's frame
ret
B: sub ESP, 20 ; allocate frame for B
; return address is at [ESP+20] in B's frame
call D
add ESP, 20 ; deallocate B's frame
ret
C: sub ESP, 12 ; allocate frame for C
; unnecessary cope of C's return address is at [ESP+12]
add ESP, 12 ; deallocate C's frame
ret
D: sub ESP, 20 ; allocate frame for D
; return address is at [ESP+20] in D's frame
call D
add ESP, 20 ; deallocate D's frame
ret
E: sub ESP, 12 ; allocate frame for E
; unnecessary cope of E's return address is at [ESP+12]
add ESP, 12 ; deallocate E's frame
ret
程序C和E都是叶子程序,因为它们不会调用任何东西。为什么这些叶子程序只能获得12位(如果我在那里也错了,请纠正我),而非叶子程序得到20位(?)?
答案 0 :(得分:0)
编译器可以使用SUB ESP,为本地分配空间 根据某些变量和/或正确对齐堆栈指针 惯例。在纯组装中,您可以设置约定 随你喜欢。不知道数字12和20来自哪里。一世 会忽略这一点并尝试下一章。
Bo Persson
可能这些代码片段是为了实现所描述的内容而发明的 在本书后面,或者它们来自更高级别的编译器输出 没有适当的反思。我希望第一个变体是真的,但是在 在这种情况下,你应该在决定之前阅读整本书 质量
通过Netch
这个字节对我来说毫无意义。
由Jester