生成一个可执行文件的完整步骤有4个:
预处理:分析源码,处理所有预处理指令(宏、条件编译、包含头文件、特殊符号等)
编译:检查源码,将源码翻译为汇编代码文件
汇编:将若干个汇编文件翻译为“若干个”目标机器指令文件(obj),此时目标文件是分散独立的。
链接:将若干个目标文件(可能还有库文件)链接成“一个”可执行文件(将有关的目标文件彼此相连接)。
首先参考一份makefile:
led.bin: start.o led.o
arm-linux-ld -Ttext 0xC0008000 -o led.elf $^
arm-linux-objcopy -O binary led.elf $@
arm-linux-objdump -D led.elf > led.dis
led.o : main.c
arm-linux-gcc -c $< -o $@
start.o : start.S
arm-linux-gcc -c $< -o $@
clean:
rm *.o *.elf *.bin *.dis
$< $@ $^的含义:
$<第一个依赖
$@目标
$^全部依赖
一、编译过程
arm-linux-gcc -c $< -o $@
-c选项:只编译、汇编为目标文件,不链接。输出文件不能直接运行。
-S选项:只编译,不汇编。
如果不指定选项, 如arm-linux-gcc $< -o $@,则完成全部编译步骤,直接输出为可执行文件$@,即led.bin
二、链接过程
ld命令:用于将多个目标、库文件链接成可执行文件
选项:
-T 指定代码段、数据段或bss段的链接地址,编译底层程序(裸机、u-boot、kernel)需要用到。编译应用程序不许要指定链接地址。
-Ttext 0x12345678 指定代码段
-Tdata 0x12345678
-Tbss 0x12345678
也可以使用链接脚本文件:
-Tlink.lds
所以,arm-linux-ld -Ttext 0xC0008000 -o led.elf $^的含义为:
将全部依赖文件(start.o led.o)链接为可执行文件led.elf
arm-linux-objcopy -O binary led.elf $@的含义为:
将led.elf文件复制为二进制可执行文件led.bin
文件的内容:
1. BIN文件是 raw binary 文件,这种文件只包含机器码。
2. ELF文件除了机器码外,还包含其它额外的信息,如段的加载地址,运行地址,重定位表,符号表等。
因为elf文件不是纯粹的可执行文件,它还包含了一些额外信息,这些信息不是机器指令,在arm开发板中不能运行,所以必须通过objcopy -O binary转化为纯粹的机器码可执行文件。
三、反汇编objdump
arm-linux-objdump -D led.elf > led.dis
将可执行文件反汇编为汇编文件。
四、补充:gcc调试选项-g
如果想得到一个含有源码对照的反汇编文件,可以使用-g选项。-g也是用于GDB调试的。
举例:
将C源代码和反汇编出来的指令对照:
1.编译成目标文件(要加-g选项)
gcc -g -o test.c
2.输出C源代码和反汇编出来的指令对照的格式
objdump -S test.o
阅读(1604) | 评论(0) | 转发(0) |