0

我在教科书中的一个练习题上遇到了麻烦。我必须填写如下所示的 C 代码的缺失部分:

int switch3(int *p1, int *p2, int action)
{
    int result = 0;
    switch(action) {
    case 1:
     // Fill in
    case 2:
     // Fill in
    default:
     // Fill in
}
     return result;
}

我遇到麻烦的原因是因为使用了指针。我很确定我知道它们是如何工作的,但让我详细说明一下。这本书为我们提供了以下 IA32 程序集以及我在评论中的注释。

Arguments: p1 at %ebp+8, p2 at %ebp+12, action at %ebp+16
 Registers: result in %edx (initialized to -1) The jump targets:

.L13 // case(1)
  movl  8(%ebp), %eax // eax = p1
  movl  (%eax), %edx  // result = *p1
  movl  12(%ebp), %ecx // ecx = p2
  movl  (%ecx), %eax   // eax = *p2
  movl 8(%ebp), %ecx  // ecx = p1 
  movl %eax, (%ecx)   // *p1 = *p2

所以最后,结果 = *p1 和 *p1 = *p2 我认为这是正确的,但接下来是什么让我感到困惑。

.L14 //case(2)
   movl  12(%ebp), %edx // result = p2  which is not possible because p2 is a pointer and result is an int
   movl  (%edx), %eax  
  movl   %eax, %edx
  movl    8(%ebp), %ecx
  addl (%ecx), %edx
  movl  12(%ebp), %eax
  movl  %edx, (%eax)
  jmp  .L19

 .L19 // default
    movl %edx, %eax

谁能帮我解决这个问题?

4

1 回答 1

2
.L14 //case(2)
  movl  12(%ebp), %edx // result = p2  which is not possible because 
                       // p2 is a pointer and result is an int

你的评论result = p2是错误的。在函数的整个持续时间内edx不绑定。result您唯一知道的是,在函数退出后,立即result存储在edx. (此外,即使与您的问题没有直接关系,程序集也没有超出其大小的类型概念,因此寄存器不知道它是否包含指针或 int。)

所以:

.L14 //case(2)
  movl  12(%ebp), %edx   // edx = p2
  movl  (%edx), %eax     // eax = *p2
  movl   %eax, %edx      // edx = eax ( = *p2 )
  movl    8(%ebp), %ecx  // ecx = p1
  addl (%ecx), %edx      // edx = edx + *p1 ( = *p1 + *p2 )
  movl  12(%ebp), %eax   // eax = p2
  movl  %edx, (%eax)     // *p2 = edx ( = *p1 + *p2 )
  jmp  .L19              // if .L19 is the end of the function, then you now know
                         // that result = *p1 + *p2
于 2013-10-10T00:31:32.653 回答