了解开关条件下的寄存器用法 [英] Understanding register usage in the switch condition
问题描述
我有一个C语言转换条件代码和汇编代码. 但是对我来说,设置,edx或eax或ecx似乎很随意?
I have a switch-condition code in C and assembly code. But it seems very arbitrary to me what to set, edx or eax or ecx?
如何分辨edx,epx,ecx,ebp之间的区别?甚至教科书也没有给我足够的解释.
How do I tell the difference between edx, epx, ecx, ebp? Even the textbook does not give me the sufficient explanation.
#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?
How do I know what is eax? Is it one of the arguments?
If so, how do I know which is the eax and ecx and which is edx?
推荐答案
在大多数汇编代码中,%eax中的内容是该函数返回的值.这就是为什么在.L19块中,%edx中的所有内容都移到%eax中的原因.往回看,无论您将result
设置为什么位置,代码都会将该值移入%edx,以便在代码跳转到.L19时,默认情况下会将值放置在%eax中.
它看起来像一个32位系统,因此它具有8个通用寄存器:
In most assembly code, whatever is in %eax is the value returned from the function. That is why in the .L19 block whatever was in %edx is moved into %eax. Looking back, wherever you set result
to something, the code moves that value into %edx so that when the code jumps to .L19 the value will be placed in %eax by default.
This looks like a 32-bit system, so it has 8 general-purpose registers:
- %ebx,%ecx,%edx,%esi和%edi是寄存器,它们大部分存储在任何给定时间保存它们所需的任何数据.
- %eax保留函数的返回值,例如调用它的函数将在更改%eax之前在%eax中查找该函数的返回值.
- %ebp和%esp是特殊的寄存器,它们实质上管理和分配堆栈上用于各种函数调用的空间.
要查看参数的放置位置,请查看代码中数据的引用位置.例如,在.L13,程序将%ebp + 8(即p1)放入%eax,然后将该地址(* p1)处的值放入%edx.因此,%edx现在拥有p1指向的值.
寄存器不保存函数的参数.不要认为默认情况下%edx包含switchmode()
的参数之一.参数总是放在堆栈上.
To see where your arguments are being placed, look at where that data is being referenced in the code. For example, at .L13, the program places %ebp+8 (which is p1) into %eax, then places the value at that address (*p1) into %edx. So, %edx now holds the value pointed to by p1.
The registers DO NOT hold the arguments to the function. Don't think that %edx contains one of the arguments to switchmode()
by default. Arguments are always placed on the stack.
这篇关于了解开关条件下的寄存器用法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!