Building the following test program using GCC:
#include <windows.h>
int main() {
Sleep(1);
return 0;
}
gcc -m64 -o main.exe main.c
In the resulting binary, the Sleep
function is called in this manner:
mov rax, [<Sleep>]
call rax
where <Sleep>
is an address in the .idata
section.
Is there a way to make gcc generate the call without using a register? I'd also be interested to know why it chooses to use two instructions here.
For comparison, the same program compiled using MSVC: cl main.c
, which yields the following:
call [<Sleep>]
where <Sleep>
is an address in the .rdata
section.
I also tried Clang: clang -o main.exe main.c
, which gives the same result as MSVC.
Compiler versions in my environment:
gcc version 14.2.0 (MinGW-W64 x86_64-ucrt-posix-seh)
Microsoft (R) C/C++ Optimizing Compiler Version 19.43.34809 for x64
clang version 18.1.8, Target: x86_64-pc-windows-msvc
Building the following test program using GCC:
#include <windows.h>
int main() {
Sleep(1);
return 0;
}
gcc -m64 -o main.exe main.c
In the resulting binary, the Sleep
function is called in this manner:
mov rax, [<Sleep>]
call rax
where <Sleep>
is an address in the .idata
section.
Is there a way to make gcc generate the call without using a register? I'd also be interested to know why it chooses to use two instructions here.
For comparison, the same program compiled using MSVC: cl main.c
, which yields the following:
call [<Sleep>]
where <Sleep>
is an address in the .rdata
section.
I also tried Clang: clang -o main.exe main.c
, which gives the same result as MSVC.
Compiler versions in my environment:
gcc version 14.2.0 (MinGW-W64 x86_64-ucrt-posix-seh)
Microsoft (R) C/C++ Optimizing Compiler Version 19.43.34809 for x64
clang version 18.1.8, Target: x86_64-pc-windows-msvc
1 Answer
Reset to default 1This behavior looks like it should be controlled by the -ffunction-cse
or -fno-function-cse
option:
-fno-function-cse
Do not put function addresses in registers; make each instruction that calls a constant function contain the function’s address explicitly.
This option results in less efficient code, but some strange hacks that alter the assembler output may be confused by the optimizations performed when this option is not used.
The default is
-ffunction-cse
However, for x86, the -fno-function-cse
option does not seem to have the desired effect of calling the when PC-relative addressing is in use, but turning on optimization with the -O
option (except for -O0
which turns off optimization) does have the desired effect of calling the function's (PC-relative) address explicitly. Note that in both cases, it is the function's import stub function that is called, since the real function's address in the DLL is not known to the linker.
发布者:admin,转转请注明出处:http://www.yc00.com/questions/1744401241a4572398.html
-fno-function-cse
optimiser setting (description: "Do not put function addresses in registers"), however it made no difference. – Cauterite Commented Mar 21 at 11:27-O
option. I'll undelete the answer I deleted earlier just in case it is useful. – Ian Abbott Commented Mar 21 at 14:55