函数参数加载到 x64 上的寄存器
function arguments loading to registers on x64
我有这个小 C 代码
void decode(int *xp,int *yp,int *zp)
{
int a,b,c;
a=*yp;
b=*zp;
c=*xp;
*yp=c;
*zp=a;
*xp=b;
}
然后我使用 gcc -c -O1 decode.c 将其编译为目标文件,然后使用 objdump -M intel -d decode.o 转储对象,等效的汇编代码是
mov ecx,DWORD PTR [rsi]
mov eax,DWORD PTR [rdx]
mov r8d,DWORD PTR [rdi]
mov DWORD PTR [rsi],r8d
mov DWORD PTR [rdx],ecx
mov DWORD PTR [rdi],eax
ret
而且我注意到它在 all.But 处不使用堆栈,首先值仍然需要加载到寄存器中。所以我的问题是 如何将参数加载到寄存器中?编译器会自动将参数加载到幕后的寄存器中吗?还是发生了其他事情? 因为没有指令将参数加载到寄存器中。
有点跑题了。当您增加编译优化时,原始源代码和机器代码之间的关系会减少,将机器代码与源代码关联起来会很困难。默认情况下,如果您不向 GCC 指定优化标志,它不会优化代码。因此,我尝试在不进行任何优化的情况下进行编译,以从源代码中获得预期的结果,但我得到的是与源代码无关且可理解的机器代码大 4-5 倍。但是当我应用 1 级优化时,代码似乎可以理解并且与源代码相关。但是为什么?
参数被加载到调用方的寄存器中。示例:
int a;
int b;
int f(int, int);
int g(void) {
return f(a, b);
}
查看为 g
生成的代码:
$ gcc -O1 -S t.c
$ cat t.s
…
movl b(%rip), %esi
movl a(%rip), %edi
call f
第二个问题:
So I tried to compile without any optimizations to get expected results from the source, but what I got was 4-5 times bigger machine code that wasnt related to the source and understandable.
发生这种情况是因为未优化的代码很愚蠢。它是中间表示的直接翻译,其中每个变量存储在堆栈中,即使它不需要,每个转换都由一个显式操作表示,即使不需要一个,等等。 -O1
是读取生成的程序集的最佳优化级别。也可以禁用帧指针,这样可以将简单函数的开销保持在最低水平。
我有这个小 C 代码
void decode(int *xp,int *yp,int *zp)
{
int a,b,c;
a=*yp;
b=*zp;
c=*xp;
*yp=c;
*zp=a;
*xp=b;
}
然后我使用 gcc -c -O1 decode.c 将其编译为目标文件,然后使用 objdump -M intel -d decode.o 转储对象,等效的汇编代码是
mov ecx,DWORD PTR [rsi]
mov eax,DWORD PTR [rdx]
mov r8d,DWORD PTR [rdi]
mov DWORD PTR [rsi],r8d
mov DWORD PTR [rdx],ecx
mov DWORD PTR [rdi],eax
ret
而且我注意到它在 all.But 处不使用堆栈,首先值仍然需要加载到寄存器中。所以我的问题是 如何将参数加载到寄存器中?编译器会自动将参数加载到幕后的寄存器中吗?还是发生了其他事情? 因为没有指令将参数加载到寄存器中。
有点跑题了。当您增加编译优化时,原始源代码和机器代码之间的关系会减少,将机器代码与源代码关联起来会很困难。默认情况下,如果您不向 GCC 指定优化标志,它不会优化代码。因此,我尝试在不进行任何优化的情况下进行编译,以从源代码中获得预期的结果,但我得到的是与源代码无关且可理解的机器代码大 4-5 倍。但是当我应用 1 级优化时,代码似乎可以理解并且与源代码相关。但是为什么?
参数被加载到调用方的寄存器中。示例:
int a;
int b;
int f(int, int);
int g(void) {
return f(a, b);
}
查看为 g
生成的代码:
$ gcc -O1 -S t.c
$ cat t.s
…
movl b(%rip), %esi
movl a(%rip), %edi
call f
第二个问题:
So I tried to compile without any optimizations to get expected results from the source, but what I got was 4-5 times bigger machine code that wasnt related to the source and understandable.
发生这种情况是因为未优化的代码很愚蠢。它是中间表示的直接翻译,其中每个变量存储在堆栈中,即使它不需要,每个转换都由一个显式操作表示,即使不需要一个,等等。 -O1
是读取生成的程序集的最佳优化级别。也可以禁用帧指针,这样可以将简单函数的开销保持在最低水平。