you can download from site: http://michgarfield./home
预备知识,阅读文章“as中常见伪指令.word .align .balign[lw] .macro .globl” C源文件到ELF可执行文件的生成过程 1. 编译器的预处理 3. 生成目标文件 4. 将目标文件链接为ELF可执行文件 ELF文件类型共有4种类型 1. 可重定位文件relocatable file 执行file xx.o,其中xx表示编译过程生成的目标文件 返回ELF 32-bit LSB relocatable, Intel 80386, version 1 (SYSV), not stripped 2. 可执行文件executable file 执行file /bin/sh ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.15, not stripped 3. 共享目标文件share object file 执行file /lib/libmemusage.so /lib/libmemusage.so: ELF 32-bit LSB shared object, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.15, stripped 4. 核心转储文件core dump file 执行file /proc/kcore ELF 32-bit LSB core file Intel 80386, version 1 (SYSV), SVR4-style, from '-3b3e-428f-91d0-1a730571'
现在通过举例说明整个编译过程,首先建立show.c和mian.c文件,其中show.c文件的内容如下 #include <stdio.h> void show() { printf ("this program is used to test ld\n"); } mian.c的内容如下 extern void show(); int main() { show(); return 0; }
用gcc加上-save-temps选项编译完成以后,可以看到汇编文件show.s内容如下 .file "show.c" .section .rodata .align 4 .LC0: .string "this program is used to test ld" .text .globl show .type show, @function show: pushl %ebp movl %esp, %ebp subl $24, %esp movl $.LC0, (%esp) call puts leave ret .size show, .-show .ident "GCC: (Ubuntu 4.4.3-4ubuntu5) 4.4.3" .section .note.GNU-stack,"",@progbits 从汇编文件show.s里可以发现汇编文件里包含了很多的伪指令,其中align4表示16字节对齐,globl是的show符号对ld可见,即全局的。所有汇编文件.text section最后都会放在ELF文件的.text section
对show.o进行反汇编(objdump –d show.o) Disassembly of section .text: 00000000 <show>: 0: 55 push %ebp 1: 89 e5 mov %esp,%ebp 3: 83 ec 18 sub $0x18,%esp 6: c7 04 24 00 00 00 00 movl $0x0,(%esp) d: e8 fc ff ff ff call e <show+0xe> 12: c9 leave 13: c3 ret 对main.o进行反汇编(objdump –d main.o) Disassembly of section .text: 00000000 <main>: 0: 55 push %ebp 1: 89 e5 mov %esp,%ebp 3: 83 e4 f0 and $0xfffffff0,%esp 6: e8 fc ff ff ff call 7 <main+0x7> b: b8 00 00 00 00 mov $0x0,%eax 10: 89 ec mov %ebp,%esp 12: 5d pop %ebp 13: c3 ret 而目标文件的生成也很简单,只是把汇编文件进行编译为对应机器码。该过程没有按照伪指令进行对齐边界,也没有进行的地址修正,对需要修正的地址只是在当前地址上+1.
链接器最后将所有的目标文件链接为ELF可执行文件,对ELF文件反汇编内容如下 080483e4 <main>: 80483e4: 55 push %ebp 80483e5: 89 e5 mov %esp,%ebp 80483e7: 83 e4 f0 and $0xfffffff0,%esp 80483ea: e8 09 00 00 00 call 80483f8 <show> 80483ef: b8 00 00 00 00 mov $0x0,%eax 80483f4: 89 ec mov %ebp,%esp 80483f6: 5d pop %ebp 80483f7: c3 ret 080483f8 <show>: 80483f8: 55 push %ebp 80483f9: 89 e5 mov %esp,%ebp 80483fb: 83 ec 18 sub $0x18,%esp 80483fe: c7 04 24 d0 84 04 08 movl $0x80484d0,(%esp) 8048405: e8 0e ff ff ff call 8048318 <puts@plt> 804840a: c9 leave 804840b: c3 ret 804840c: 90 nop 804840d: 90 nop 804840e: 90 nop 804840f: 90 nop 在链接器链接完成以后可以看出main函数调用show函数的地址和show函数对printf函数的地址都变成绝对地址,而且程序在最后加入了4条nop操作,使得以16字节对齐。 |
|
来自: 昵称19263926 > 《c/c 》