测试在 x86 32 位 Linux、Ubuntu 12.04、GCC 4.6.3 objdump 2.22
基本上当我gcc用来生成foo这样的函数的汇编代码时:
gcc -S foo.c -O2
在 function 的末尾foo,我可以得到这样的指令序列(我修改了它并附上了每条指令及其机器代码以使其清晰):
......
1977 .cfi_restore_state
1978 8B150000 0000 movl nodes, %edx
1979 89442410 movl %eax, 16(%esp)
1980 A1000000 00 movl i_depth, %eax
1981 8974240C movl %esi, 12(%esp)
1982 C7442404 FC000000 movl $.LC55, 4(%esp)
1983 89542414 movl %edx, 20(%esp)
1984 89442408 movl %eax, 8(%esp)
1985 C7042401 000000 movl $1, (%esp)
1986 E8FCFFFF FF call __printf_chk
1987 E937FFFF FF jmp .L181
1988 .L186:
1989 E8FCFFFF FF call __stack_chk_fail
foo1:
这看起来很正常。
但是,当我编译+链接以创建ELF可执行文件,然后objdump像这样反汇编它时:
gcc foo.c -O2
objdump -Dr -j .text foo
反汇编器产生的指令是这样的(为了更容易理解,我做了一点修改):
11856 89442410 mov %eax,0x10(%esp)
11857 A1000000 00 mov 0x80851AC,%eax
11858 8974240C mov %esi,0xC(%esp)
11859 C7442404 00000000 movl $S_0x8064658,0x4(%esp)
11860 89542414 mov %edx,0x14(%esp)
11861 89442408 mov %eax,0x8(%esp)
11862 C7042401 000000 movl $0x1,(%esp)
11863 E8FCFFFF FF call __printf_chk
11864 E933FFFF FF jmp 0x80547EB
11865
11866 E8FCFFFF FF S_0x80548BC : call __stack_chk_fail
11867 EB0D jmp foo1
11868 90 nop
11869 90 nop
11870 90 nop
11871 90 nop
11872 90 nop
11873 90 nop
11874 90 nop
11875 90 nop
11876 90 nop
11877 90 nop
11878 90 nop
11879 90 nop
11880 90 nop
11881 foo1:
查看函数的结尾foo,我发现了在原始汇编代码中找不到的指令序列。
这似乎是一个填充问题,但我不确定。
所以我的问题是:
- 这些指令序列是做什么用的?
- 无论如何要告诉(汇编程序?链接器?)不要生成这些指令序列..?因为基本上我正在使用汇编代码分析工具,而这些指令序列很烦编码。
