Linux gcc“;“你好,世界”;比预期大10倍的二进制文件
我跟在后面。(如果您搜索“624 a.out”,这就是我所在的位置)。我的二进制文件的大小是8480字节,而文章的大小则低至624字节!我显然做错了什么,但我不知道是什么。奇怪的是,removing-static将二进制大小增加到13264!到目前为止,我在网上找到的所有东西都在谈论gcc在使用标准库(我没有使用)时如何添加一堆东西,或者静态链接占用了一堆空间(目前我不相信我正在链接任何东西) 我的终端Linux gcc“;“你好,世界”;比预期大10倍的二进制文件,linux,gcc,x86-64,Linux,Gcc,X86 64,我跟在后面。(如果您搜索“624 a.out”,这就是我所在的位置)。我的二进制文件的大小是8480字节,而文章的大小则低至624字节!我显然做错了什么,但我不知道是什么。奇怪的是,removing-static将二进制大小增加到13264!到目前为止,我在网上找到的所有东西都在谈论gcc在使用标准库(我没有使用)时如何添加一堆东西,或者静态链接占用了一堆空间(目前我不相信我正在链接任何东西) 我的终端 $ gcc -s -Og -march=native -static -nostdlib -
$ gcc -s -Og -march=native -static -nostdlib -fno-exceptions -fno-unwind-tables -fno-rtti -fno-asynchronous-unwind-tables start.S main.cpp
$ wc -c a.out
8744 a.out
$ strip -R .comment a.out
$ strip -R .note.gnu.property a.out
$ strip -R .note.gnu.build-id a.out
strip: a.out: warning: empty loadable segment detected at vaddr=0x400000, is this intentional?
$ wc -c a.out
8480 a.out
$ ./a.out
hello
start.S
#ifdef __linux__
#ifdef __LP64__
.intel_syntax noprefix
.text
.globl _start, syscall5
_start:
xor rbp,rbp
pop rdi
mov rsi,rsp
and rsp,-16
call main
mov rdi,rax /* syscall param 1 = rax (ret value of main) */
mov rax,60 /* SYS_exit */
syscall
ret /* should never be reached, but if the OS somehow fails
to kill us, it will cause a segmentation fault */
syscall5:
mov rax,rdi
mov rdi,rsi
mov rsi,rdx
mov rdx,rcx
mov r10,r8
mov r8,r9
syscall
ret
#endif
#endif
main.cpp
extern "C"
void* syscall5(
void* number,
void* arg1,
void* arg2,
void* arg3,
void* arg4,
void* arg5
);
int main(int argc, char* argv[])
{
syscall5(
(void*)1, /* SYS_write */
(void*)1,
(void*)"hello\n",
(void*)6,
0, /* ignored */
0 /* ignored */
);
return 0;
}
编辑:
添加-Wl,--nmagic将二进制文件缩小到更接近我预期的大小。似乎对链接器所做的一些安全性更改导致了额外的填充 这回答了你的问题吗@wxz不,这里的额外大小不是因为汇编指令。看起来几乎所有大小都是空字节,以填充到0x1000和0x2000位置。但我不完全确定原因。使用
-nostlib
,没有任何额外的东西与-static
(没有libc,没有CRT启动文件)链接,因此没有理由期望-static
增加可执行文件的大小<代码>-静态意味着-没有饼图
,没有饼图,您仍然会得到一个动态链接的可执行文件。