1

有人可以帮我理解 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
*/
4

1 回答 1

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)。我猜这可能是一些学习组装的交易,而不是实际的测试方法。

于 2012-07-10T13:01:50.780 回答