测试平台在 Linux 32 位 x86 上。所以基本上我写了一个简单的 C 程序,如下所示:
void main()
{
double a = 10.0;
printf("hello world %f\n", a);
}
我用gcc编译成ELF二进制文件,然后用objdump反汇编。我解决了对 .rodata 部分的引用,并在此改进了 asm 代码:
extern printf
section .rodata
S_80484d0 db 0x68
db 0x65
db 0x6c
db 0x6c
db 0x6f
db 0x20
db 0x77
db 0x6f
db 0x72
db 0x6c
db 0x64
db 0x20
db 0x25
db 0x66
db 0x0a
S_80484f0 db 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x24, 0x40
section .text
global main
main:
push ebp
mov ebp,esp
and esp,0xfffffff0
sub esp,0x20
fld qword [S_80484f0]
fstp QWORD [esp+0x18]
fld QWORD [esp+0x18]
fstp QWORD [esp+0x4]
mov DWORD [esp],S_80484d0
call printf
leave
ret
然后我重新编译这个 asm 代码以获得一个新的 ELF 二进制文件,并比较这两个二进制文件的 .text 部分。
这是令人困惑的事情:我能找到的唯一不同是在主函数前面有更多的领先 nop 像这样:
新的 ELF 二进制前导 nop:

新的 ELF 二进制结尾 nop:

旧的 ELF 二进制文件:

基本上我认为这不是“对齐”问题,因为 nop 太多了。
更何况,当我把原来的代码改成简单的helloworld代码(没有双号a),那么这两个ELF二进制文件基本上没有区别。
任何人都可以帮我解释为什么会生成这么多 nop 吗?
谢谢