有人可以帮我理解push_test()和pop_test()方法试图测试的内容吗?这些方法试图测试一些东西,我无法弄清楚那是什么。
以下代码用c:
编写int push_test() {
int ret_val;
/* movl %esp, %eax ;; save stack pointer
pushl %esp ;; push stack pointer onto stack
popl %edx ;; pop the stack into %edx
subl %edx, %eax ;; subtract the two values
movl %eax, ret_val ;; set up the return value
*/
asm("movl %%esp, %%eax; pushl %%esp; popl %%edx; subl %%edx, %%eax; movl %%eax, %0"
: "=r" (ret_val)
: /* no input */
: "%edx", "%eax");
return ret_val;
}
int pop_test() {
int ret_val = 0xffffffff; /* -1 in decimal */
/* pushl ret_val ;; save ret_val on the stack
movl %esp, %edx ;; save the stack pointer
popl %esp ;; pop stack into the stack pointer
movl %esp, ret_val ;; set the popped value as the return value
movl %edx, %esp ;; restore original stack pointer
*/
asm("pushl %1; movl %%esp, %%edx; popl %%esp; movl %%esp, %0; movl %%edx, %%esp"
: "=r" (ret_val)
: "r" (ret_val)
: "%edx");
return ret_val;
}
int main() {
printf("push test: %d\n", push_test());
printf("pop test: %d\n", pop_test());
}
/* Output:
push test: 0
pop test: -1
*/
答案 0 :(得分:2)
您的push_test()
和pop_test()
正在保存堆栈状态,从而破坏堆栈帧,
然后根据堆栈上的值进行操作。
让我们浏览pop_test()
的每条指令并找出它的作用(push_test()
在操作中非常相似)。
pushl ret_val
将-1推入堆栈,递增堆栈指针(%esp
),所以现在你的堆栈看起来像是:{-1}
。
movl %esp, %edx
将您的堆栈指针复制到%edx
,因此%edx
包含堆栈上位置1的内存地址,所以现在您的堆栈看起来像:{-1}
, %esp
:stack[1]
,%edx
:stack[1]
popl %esp
弹出-1并将其存储到%esp
中,因此堆栈如下所示:{}
,%esp
:-1
,%edx
:stack[1]
movl %esp, ret_val
获取%esp
的值,当前为-1,并将其移至ret_val
,因此ret_val
变为-1。
最后movl %edx, %esp
将%edx
的值放回%esp
并返回-1。
此方法始终返回-1。我们的想法是将值推入堆栈,将其弹回,然后查看值是否保持不变。它还会破坏和改造堆栈(通过暂时销毁然后恢复%esp
)。我猜这可能是一些学习装配的一种交易,而不是一种实际的测试方法。