1.32k likes | 1.53k Views
基于 s3c44B0X 嵌入式 uCLinux 系统原理及应用. 主讲人:李岩 哈尔滨理工大学计算机学院. 本章主要内容:. (1)GCC 编译过程 (2)C/C++ 交叉编译器 arm-elf-gcc (3) 交叉汇编器 arm-elf-as (4) 交叉连接器 arm-elf-l d (5) 工程管理器 make (6) 汇编语言编程 (7) 混合编程. 第 3 章 目录. ★ 1 GNU GCC 简介 ★ 2 C/C++ 交叉编译器 arm-elf-gcc ★3 交叉连接器 arm-elf-ld 3.1 需求分析
E N D
基于s3c44B0X嵌入式uCLinux系统原理及应用 主讲人:李岩 哈尔滨理工大学计算机学院
本章主要内容: (1)GCC编译过程 (2)C/C++交叉编译器arm-elf-gcc (3)交叉汇编器 arm-elf-as (4)交叉连接器arm-elf-l d (5)工程管理器make (6)汇编语言编程 (7)混合编程
第 3 章 目录 ★1 GNU GCC简介 ★2 C/C++交叉编译器arm-elf-gcc ★3 交叉连接器arm-elf-ld 3.1 需求分析 ★4 工程管理器 MAKE ★5 交叉汇编器 arm-elf-as ★6 汇编语言编程 ★7 简单程序设计 ★8 混合语言编程
第 3 章 目录 ★1 GNU GCC简介 ★2 C/C++交叉编译器arm-elf-gcc ★3 交叉连接器arm-elf-ld 3.1 需求分析 ★4 工程管理器 MAKE ★5 交叉汇编器 arm-elf-as ★6 汇编语言编程 ★7 简单程序设计 ★8 混合语言编程
3.1 GNU GCC简介 GNU集成编译环境GCC(GNU Compiler Collection)是一种面向嵌入式领域、支持多种编程语言、支持多种CPU的交叉编译工具。 • GNU GCC的基本功能 输出预处理后的C/C++源程序(展开头文件和替换宏) 输出C/C++源程序的汇编代码 输出二进制目标文件 生成静态库 生成可执行程序 转换文件格式
3.1 GNU GCC简介 • GCC组成 --------------C/C++交叉编译器arm-elf-gcc arm-elf-gcc是编译的前端程序,它通过调用其 他程序来实现将程序源文件编译成目标文件的功能。 arm-elf-gcc具有丰富的命令选项,可以控制编译的各个阶段,满足用户的各种编译需求。
3.1 GNU GCC简介 • GCC组成 --------------汇编器 arm-elf-as arm-elf-as将汇编语言程序转换为ELF (Executable and Linking Format,执行时链接文件格式)格式的可重定位目标代码,这些目标代码同其它目标模块或函数库易于定位和链接。 说明:arm-elf-as产生一个交叉参考表和一个标准的符号表,产生的代码和数据能够放在多个区 (Section)中。
3.1 GNU GCC简介 • GCC组成 --------------连接器arm-elf-ld arm-elf-gcc是编译的前端程序,arm-elf-ld根据 链接定位文件Linkcmds中的代码区、数据区、BSS 区和栈区等定位信息,将可重定位的目标模块链接 成一个单一的、绝对定位的目标程序。
3.1 GNU GCC简介 • GCC组成 --------------库管理器arm-elf-ar arm-elf-ar将多个可重定位的目 标模块归档为一个函数库文件。
3.1 GNU GCC简介 • GCC组成 --------------工程管理器MAKE arm-elf-gcc Make是用于自动编译、链接程序的实用工具,使用make后就不需要手工的编译每个程序文件。要使用make,首先要编写makefile。 Makefile描述程序文件之间的依赖关系, 并提供更新文件的命令。
3.1 GNU GCC简介 • GCC组成 -------------其他实用程序 arm-elf-objcopy目标文件格式转换工具等;
3.1 GNU GCC简介 • GCC编译程序的基本过程 • arm-elf-gcc根据输入文件的后缀来确定文件的类型,然后根据用户的编译选项(包括优化选项、调试信息选项等)将其编译成相应的汇编临时文件(后缀为.s); • arm-elf-as将该汇编文件编译成目标文件(后缀为.o); • arm-elf-ld根据用户的链接选项(包括指定链接命令文件等)将目标文件和各种库链接起来生成可执行文件。 程序的编译过程
头文件 C/C++源文件 Arm-elf-gcc 汇编文件 Arm-elf-as 源文件列表 目标文件 生成库 连接命令文件 库列表 Arm-elf-ar 用户库 可重定位模块 Arm-eif-ld 可执行程序
第 3 章 目录 ★1 GNU GCC简介 ★2 C/C++交叉编译器arm-elf-gcc ★3 交叉连接器arm-elf-ld 3.1 需求分析 ★4 工程管理器 MAKE ★5 交叉汇编器 arm-elf-as ★6 汇编语言编程 ★7 简单程序设计 ★8 混合语言编程
3.2 C/C++交叉编译器arm-elf-gcc ------------------命令格式 • 概述 arm-elf-gcc [options] file… 在命令arm-elf-gcc后面跟一个或多个选项,选项间用空格隔开,然后跟一个或多个目标文件。 例如,将test.c 编译成目标文件test.o 并且生成调试信息: arm-elf-gcc –g –c –o test.o test.c
3.2 C/C++交叉编译器arm-elf-gcc ------------------命令选项列表 • 概述 输出控制选项: -c 将输入的源文件编译成目标文件 -S 将C/C++文件生成汇编文件 -o file 将输出内容存于文件file -pipe 在编译的不同阶段之间采用管道通讯方式 -v 打印出编译过程中执行的命令 -x language 说明文件的输入类型为language
3.2 C/C++交叉编译器arm-elf-gcc ------------------命令选项列表 • 概述 C语言选项: -ansi 支持所有ANSI C程序
3.2 C/C++交叉编译器arm-elf-gcc ------------------命令选项列表 • 概述 警告选项: -w 关闭所有警告 -Wall 打开所有警告 -Wimplicit 如果有隐含申明,显示警告信息 -Wno-implicit 不显示对隐含申明的警告
3.2 C/C++交叉编译器arm-elf-gcc ------------------命令选项列表 • 概述 调试选项: -g 在文件中产生调试信息(调试信息的文件格式有stabs、COFF、XCOFF、DWARF)
3.2 C/C++交叉编译器arm-elf-gcc ------------------命令选项列表 • 概述 优化选项: -O0 不优化 -O1 一级优化 -O2 二级优化 -O3 三级优化
3.2 C/C++交叉编译器arm-elf-gcc ------------------命令选项列表 • 概述 预处理选项: -E 运行C的预处理器 -C 在运用-E进行预处理时不去掉注释 -D macro 定义宏macro为1 -D macro=defn 定义宏macro为defn
3.2 C/C++交叉编译器arm-elf-gcc ------------------命令选项列表 • 概述 汇编选项: -Wa,option 将选项option传递 给汇编器
3.2 C/C++交叉编译器arm-elf-gcc ------------------命令选项列表 • 概述 搜索路径选项: -I dir 设置搜索路径为dir -I- 指定只对 #include “file”,有效的头文件搜索目录
3.2 C/C++交叉编译器arm-elf-gcc ------------------源文件类型的识别 • 概述 arm-elf-gcc能够自动根据文件名后缀识别文件类型. *.c ——C源文件 *.i ——经过预处理后的C源文件 *.h ——C头文件 *.ii ——经过预处理后的C++源文件 *.cc ——C++源文件 *.cxx ——C++源文件 *.cpp ——C++源文件 *.C ——C++源文件 *.s ——不需要预处理的汇编文件 *.S ——需要预处理的汇编文件
3.2 C/C++交叉编译器arm-elf-gcc -----------输出文件名的指定 • 命令使用 -o file 将输出内容存于文件file,仅适用于只有一个输出文件时。 例如,将test.c编译成汇编程序并存放于文件test.txt: arm-elf-gcc –S –o test.txt test.c
3.2 C/C++交叉编译器arm-elf-gcc -----------目标文件的生成 • 命令使用 -c 将输入的源文件编译成目标文件。 例如,将test.c编译成test.o: arm-elf-gcc –c –o test.o test.c
3.2 C/C++交叉编译器arm-elf-gcc ---------将C/C++文件生成汇编文件 • 命令使用 -S 将C/C++文件生成汇编文件。 例如,将test.c编译生成汇编文件test.s: arm-elf-gcc –S –o test.s test.c
3.2 C/C++交叉编译器arm-elf-gcc ---------预处理文件的生成 • 命令使用 -E 只对源文件进行预处理并且缺省输出到标准输出。 例如,对test.c进行预处理并将结果输出到屏幕: arm-elf-gcc –E test.c
3.2 C/C++交叉编译器arm-elf-gcc ---------设置头文件搜索路径 • 命令使用 头文件的引用有两种形式: 一种是# include“filename”, 一种是# include <filename>。 前一种形式的路径搜索顺序是:当前目录、指定的搜索路径;后一种形式只搜索指定路径。 -I dir 将目录dir添加到头文件搜索目录列表的第一项。 -I- -I-以前用-I指定的头文件搜索目录只对 # include“file” 有效,对 # include<file> 无效; -I-以后指定的头文件搜索目录对以上两种形式的头文件都有效。
3.2 C/C++交叉编译器arm-elf-gcc ---------设置头文件搜索路径 • 命令使用 头文件的引用有两种形式: 一种是# include“filename”, 一种是# include <filename>。 前一种形式的路径搜索顺序是:当前目录、指定的搜索路径;后一种形式只搜索指定路径。 -I dir -I- 例如,编译test.c,在当前目录和/include中搜索test.c所包含的头文件: arm-elf-gcc –I ./ –I/include –c test.c
3.2 C/C++交叉编译器arm-elf-gcc ---------控制警告产生 • 命令使用 可以使用以-W开头的不同选项对特定警告进行设定。对于每种警告类型都有相应以-Wno-开始的选项关闭警告。 例如,如果有隐含申明,显示警告信息: arm-elf-gcc –c –Wimplicit test.c 不显示对隐含申明的警告: arm-elf-gcc –c –Wno–implicit test.c 常用的警告选项有: -w关闭所有警告信息。 -Wall打开所有警告信息。
3.2 C/C++交叉编译器arm-elf-gcc ---------实现优化 • 命令使用 arm-elf-gcc支持多种优化选项,总体上划分为三级优化: -O1可以部分减小代码尺寸,对运行速度有一定的提高。较多地使用了寄存器变量,提高指令的并行度。 -O2除了解循环、函数插装和静态变量优化,几乎包含arm-elf-gcc所有优化选项。一般在生成固化代码时使用该选项较为适宜。 -O3包含-O2的所有优化,并且还包含了解循环、函数插装和静态变量优化。通常情况下,该级优化生成的代码执行速度最快,但是代码尺寸比-O2大一些。
3.2 C/C++交叉编译器arm-elf-gcc ---------在命令行定义 • 命令使用 -D macro定义宏macro为1。 -D macro=defn定义宏macro为defn。 例如: 编译test.c并且预定义宏 RUN_CACHE 值为1: arm-elf-gcc –c –D RUN_CACHE test.c 编译test.c并且预定义宏 RUN_CACHE 值为0: arm-elf-gcc –c –D RUN_CACHE=0 test.c
第 3 章 目录 ★1 GNU GCC简介 ★2 C/C++交叉编译器arm-elf-gcc ★3 交叉连接器arm-elf-ld ★4 工程管理器 MAKE ★5 交叉汇编器 arm-elf-as ★6 汇编语言编程 ★7 简单程序设计 ★8 混合语言编程
3.2 交叉连接器arm-elf-ld ---------命令格式 • 概述 arm-elf-ld [option] file… 命令行后跟选项和可重定位的目标文件名。 例如: 链接的输入文件为demo.o,输出文件为demo.elf,链接的库为libxxx.a,生成内存映象文件map.txt,链接定位文件为linkcmds,则命令如下: arm-elf-ld -Map map.txt -T linkcmds -L./lib –o demo.elf demo.o –lxxx
3.2 交叉连接器arm-elf-ld ---------命令选项列表 • 概述 -e entry 指定程序入口 -M 输出链接信息 -lar 指定链接库 -L dir 添加搜索路径 -o 设置输出文件名 -Tcommandfile 指定链接命令文件 -v 显示版本信息 -Map 制定输出映像文件
3.2 交叉连接器arm-elf-ld ---------程序入口地址 • 命令使用 -e entry 以符号entry作为程序执行的入口地址,而不从默认的入口地址开始。 例如:链接的输入文件为demo.o,输出文件为demo.elf,链接定位文件为linkcmds,将入口地址设为_start,命令如下: arm-elf-ld –T linkcmds –e _start –o demo.elf demo.o
3.2 交叉连接器arm-elf-ld ---------输出链接信息 • 命令使用 -M 在标准端口打印出符号映象表和内存分布信息。 例如:链接的输入文件为demo.o,输出文件为demo.elf,在标准端口打印出符号映象表和内存分布信息,命令如下: arm-elf-ld –M –o demo.elf demo.o 如果标准输出设置为显示器,运行命令后将在显示器上显示内存映象信息和符号映象表。
3.2 交叉连接器arm-elf-ld ---------输出链接信息 • 命令使用 -Map mapfile 将链接的符号映象表和内存分布信息输出到文件mapfile里。 例如:链接的输入文件为demo.o,输出文件为demo.elf,将链接的符号映象表和内存分布信息输出到文件map.txt里,命令如下: arm-elf-ld –Map map.txt –o demo.elf demo.o
3.2 交叉连接器arm-elf-ld ---------指定链接的库出 • 命令使用 -lar 指定库文件libar.a为链接的库。 可以重复使用-l来指定多个链接的库。 例如:链接的输入文件为demo.o,指定libxxx.a为链接的库,输出文件为demo.elf,命令如下: arm-elf-ld –o demo.elf demo.o –lxxx
3.2 交叉连接器arm-elf-ld ---------添加库和脚本文件的搜索路径 • 命令使用 -Ldir 将dir添加到搜索路径。 例如:例如:链接的输入文件为demo.o,输出文件为demo.elf,将/lib添加到库的搜索路径,命令如下: arm-elf-ld -L./lib –o demo.elf demo.o
3.2 交叉连接器arm-elf-ld ---------设置输出文件的名字 • 命令使用 -o output 将输出文件名字设定为output。如果不指定输出文件名, arm-elf-ld生成文件名默认为a.out。 例如:链接的输入文件为demo.o,输出文件为demo.elf,命令如下: arm-elf-ld –o demo.elf demo.o
3.2 交叉连接器arm-elf-ld • linkcmds连接命令文件 -----调用linkcmds 首先写一个链接命令文件linkcmds,然后在arm-elf-ld的命令中使用-T linkcmds参数,就能在链接时自动调用linkcmds文件. 例如:链接的输入文件为demo.o,输出文件为demo.elf,链接定位文件为linkcmds,则命令如下: arm-elf-ld –T linkcmds –o demo.elf demo.o
3.2 交叉连接器arm-elf-ld • linkcmds连接命令文件 -----编写linkcmds arm-elf-ld的命令语言是一种描述性的脚本语言,它主要应用于控制:有哪些输入文件、文件的格式怎样、输出文件中的模块怎样布局、分段的地址空间怎样分布、以及未初始化的数据段怎样处理等。 用命令语言写成的文件(通常称为linkcmds)具有可重用性,不必每次在命令行输入一大堆命令选项.并且对于不同的应用,只需对linkcmds进行简单的修改就可以使用。
3.2 交叉连接器arm-elf-ld • linkcmds连接命令文件 -----编写linkcmds (1)arm-elf-ld命令语言 (2)表达式 (3)linkcmds的结构 (4)对程序入口的说明 (5)对程序头的说明 (6)对内存布局的说明 (7)对分段的说明 (8)注释
第 3 章 目录 ★1 GNU GCC简介 ★2 C/C++交叉编译器arm-elf-gcc ★3 交叉连接器arm-elf-ld ★4 工程管理器 MAKE ★5 交叉汇编器 arm-elf-as ★6 汇编语言编程 ★7 简单程序设计 ★8 混合语言编程
3.3工程管理器 make ---------命令格式 • 概述 make [-f makefile] [option] [target]… make命令后跟-f选项,指定makefile的名字为makefile; option表示make的一些选项 ;target是make指定的目标,在3.4.3将详细说明。 例如:makefile的名字是 my_hello_make: make –f my_hello_make
3.3工程管理器 make ---------命令选项列表 • 概述 -f 指定makefile -e 使环境变量优先于makefile的变量 -I dir 设定搜索目录 -i 忽略make过程中所有错误 -n 只显示执行过程,而不真正执行 -r 使隐含规则无效 -w 显示工作目录 -C dir 读取makefile设置的工作目录 -s 不显示执行的命令
3.3工程管理器 make ---------指定makefile • 命令使用 -f makefile 用该选项指定makefile的名字为makefile。 如果make中多次使用-f指定多个makefile,则所有makefile将链接起来作为最后的makefile。 如果不指定makefile,make默认的makefile依次为“makefile”、“Makefile”。 例如:make –f my_hello_make
3.3工程管理器 make • 命令使用 ---------指定环境变量优先于makefile 文件中的变量 -e 使环境变量优先于makefile文件中的变量。 例如: make –e