gpt4 book ai didi

c - 了解开关条件下的寄存器用法

转载 作者:行者123 更新时间:2023-11-30 17:45:28 25 4
gpt4 key购买 nike

我有一个 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;
}

汇编代码是

Arguments:  p1      at %ebp+8
p2 at %ebp+12
action at %ebp+16

Register: result in %edx (initialized to -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?

最佳答案

在大多数汇编代码中,%eax 中的内容都是函数返回的值。这就是为什么在 .L19 block 中 %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() 的参数之一。参数始终放置在堆栈中。

关于c - 了解开关条件下的寄存器用法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19624330/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com