C推&流行测试

时间:2012-07-10 12:54:50

标签: c assembly x86

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

1 个答案:

答案 0 :(得分:2)

您的push_test()pop_test()正在保存堆栈状态,从而破坏堆栈帧, 然后根据堆栈上的值进行操作。

让我们浏览pop_test()的每条指令并找出它的作用(push_test()在操作中非常相似)。

pushl ret_val将-1推入堆栈,递增堆栈指针(%esp),所以现在你的堆栈看起来像是:{-1}

movl %esp, %edx将您的堆栈指针复制到%edx,因此%edx包含堆栈上位置1的内存地址,所以现在您的堆栈看起来像:{-1}%espstack[1]%edxstack[1]

popl %esp弹出-1并将其存储到%esp中,因此堆栈如下所示:{}%esp-1%edxstack[1]

movl %esp, ret_val获取%esp的值,当前为-1,并将其移至ret_val,因此ret_val变为-1。

最后movl %edx, %esp%edx的值放回%esp并返回-1。


此方法始终返回-1。我们的想法是将值推入堆栈,将其弹回,然后查看值是否保持不变。它还会破坏和改造堆栈(通过暂时销毁然后恢复%esp)。我猜这可能是一些学习装配的一种交易,而不是一种实际的测试方法。