C,汇编:了解开关条件,edx eax ecx

时间:2013-10-27 22:19:38

标签: c pointers assembly

C,汇编:了解开关条件,edx eax ecx

我在C和汇编代码中有一个开关条件代码。 但对我来说,设置edx或eax或ecx似乎很随意? 我如何区分edx,epx,ecx,ebp?即使是教科书也没有给我足够的解释。

#include <stdio.h>

// Enumerated type creates set of constants
// numbered 0 and upward
typedef enum {MODE_A, MODE_B, MODE_C, MODE_D, MODE_E} mode_t;

int switchmode(int *p1, int *p2, mode_t action)
{
  int result = 0;
  switch(action) {
    case MODE_A:
      result = *p1;
      *p1 = *p2;
      break;
    case MODE_B:
      *p2 += *p1;
      result = *p2;
      break;
    case MODE_C:
      *p2 = 15;
      result = *p1;
      break;
    case MODE_D:
      *p2 = *p1;
      /* Fall Through */
    case MODE_E:
      result = 17;
      break;
    default:
      result = -1;
  }
  return result;
}

int main(int argc, const char * argv[])
{
  int num1 = 10;
  int num2 = 20;

  printf("MODE_A: %d \n", switchmode(&num1, &num2, MODE_A)); // 10
  printf("MODE_B: %d \n", switchmode(&num1, &num2, MODE_B)); // 40
  printf("MODE_C: %d \n", switchmode(&num1, &num2, MODE_C)); // 20
  printf("MODE_D: %d \n", switchmode(&num1, &num2, MODE_D)); // 17
  printf("MODE_E: %d \n", switchmode(&num1, &num2, MODE_E)); // 17
  printf("NULL: %d \n", switchmode(&num1, &num2, (mode_t) NULL)); // 20
    return 0;
}

汇编代码是

参数:p1 at%ebp + 8             p2 at%ebp + 12             行动在%ebp + 16 注册:结果%edx(初始化为-1)

.L17: // MODE_E
  movl $17, %edx
  jmp .L19
.L13: // MODE_A
  movl 8(%ebp), %eax
  movl (%eax), %edx
  movl 12(%ebp), %ecx
  movl (%ecx), %eax
  movl 8(%ebp), %ecx
  movl %eax, (%ecx)
  jmp .L19
.L14: // MODE_B
  movl 12(%ebp), %edx
  movl (%edx), %eax
  movl %eax, %edx
  movl 8(%ebp), %ecx
  addl (%ecx), %edx
  movl 12(%ebp), %eax
  movl %edx, (%eax)
  jmp .L19
.L15: // MODE_C
  movl 12(%ebp), %edx
  movl $15, (%edx)
  movl 8(%ebp), %ecx
  movl (%ecx), %edx
  jmp .L19
.L16: // MODE_D
  movl 8(%ebp), %edx
  movl (%edx), %eax
  movl 12(%ebp), %ecx
  movl %eax, (%ecx)
  movl $17, %edx
.L19: // default
  movl %edx, %eax // set return value

我的问题是 我怎么知道什么是eax?这是其中一个论点吗? 如果是这样,我怎么知道哪个是eax和ecx哪个是edx?

提前致谢!

1 个答案:

答案 0 :(得分:0)

在大多数汇编代码中,%eax中的任何内容都是函数返回的值。这就是为什么在.L19块中,%edx中的任何内容都被移动到%eax中。回顾一下,无论您将result设置为什么,代码都会将该值移动到%edx中,这样当代码跳转到.L19时,默认情况下该值将放在%eax中。
这看起来像一个32位系统,因此它有8个通用寄存器:

  • %ebx,%ecx,%edx,%esi和%edi是寄存器,主要存储在任何给定时间保存它们所需的任何数据。
  • %eax保存函数的返回值,例如调用它的函数将在%eax中查找该函数的返回值,然后再更改%eax。
  • %ebp和%esp是特殊的寄存器,基本上管理和分配堆栈上的空间以进行各种函数调用。

要查看放置参数的位置,请查看代码中引用数据的位置。例如,在.L13,程序将%ebp + 8(即p1)放入%eax,然后将该地址(* p1)的值放入%edx。因此,%edx现在保持p1指向的值。

寄存器不保存函数的参数。不要认为%edx默认包含switchmode()的一个参数。参数总是放在堆栈上。