Chinaunix首页 | 论坛 | 博客
  • 博客访问: 480061
  • 博文数量: 100
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 955
  • 用 户 组: 普通用户
  • 注册时间: 2014-11-21 09:30
文章分类

全部博文(100)

文章存档

2017年(1)

2016年(16)

2015年(83)

我的朋友

分类: 嵌入式

2015-08-08 17:16:40

生成一个可执行文件的完整步骤有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





阅读(1614) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~