开发环境的搭建和开发工具   分类:其他 | 上传于: 2019-12-06 18:14:58

1."嵌入式操作系统
陈香兰
xlanchen@ustc.edu.cn
助教:陈博、李春华
" 2."GNU开发工具链介绍
\t\t\t
“工欲善其事,
必先利其器”
--《论语》
" 3."2019/11/1 Friday
Embedded Operating Systems
3/107
主要内容
GNU Tools简介
GNU Tools交叉开发环境及其安装
" 4."2019/11/1 Friday
Embedded Operating Systems
4/107
本地开发 vs 交叉平台开发
本地开发: 一般软件的开发属于本地开发,也就是说开发软件的系统与运行软件的系统是相同的。
交叉平台开发: 本课程所涉及到的嵌入式系统开发属于交叉平台开发,也就是说开发软件的系统与运行软件的系统不同。
" 5."2019/11/1 Friday
Embedded Operating Systems
5/107
交叉开发平台
主机: 开发软件的平台,称为主机,往往是通用电脑;
目标机: 运行软件的平台,称为目标机,在这里是嵌入式系统。
" 6."2019/11/1 Friday
Embedded Operating Systems
6/107
嵌入式交叉开发工具
掌握嵌入式开发工具的使用是进行嵌入式开发的前提条件之一
与主流开发工具类似,嵌入式交叉开发工具也包括
编译器,即能够把一个源程序编译生成一个可执行程序的软件
调试工具,即能够对执行程序进行源码或汇编级调试的软件
软件工程工具,用于协助多人开发或大型软件项目的管理的软件
" 7."2019/11/1 Friday
Embedded Operating Systems
7/107
GNU tools
GNU tools和其他一些优秀的开源软件可以完全覆盖上述类型的软件开发工具。为了更好的开发嵌入式系统,需要熟悉如下一些软件
GCC
Binutils—辅助GCC的主要软件
Gdb
make
cvs
" 8."2019/11/1 Friday
Embedded Operating Systems
8/107
一、GCC
很多人认为GCC只是一个C编译器, 其实GCC = GNU Compiler Collection
目前,GCC可以支持多种高级语言,如
C、C
ADA
Object C
JAVA
Fortran
PASCAL
" 9."2019/11/1 Friday
Embedded Operating Systems
9/107
GCC下的工具
cpp — 预处理器 GNU C编译器在编译前自动使用cpp对用户程序进行预处理
gcc — 符合ISO等标准的C编译器
g — 基本符合ISO标准的C 编译器
gcj — GCC的java前端
gnat — GCC的GNU ADA 95前端
" 10."2019/11/1 Friday
Embedded Operating Systems
10/107
GNU Tools—gcc
gcc是一个强大的工具集合,它包含了预处理器、编译器、汇编器、链接器等组件。它会在需要的时候调用其他组件。 输入文件的类型和传递给gcc的参数决定了gcc调用具体的哪些组件。
对于开发者,它提供的足够多的参数,可以让开发者全面控制代码的生成,这对嵌入式系统级的软件开发非常重要
" 11."2019/11/1 Friday
Embedded Operating Systems
11/107
gcc使用举例(1) 源程序
" 12."2019/11/1 Friday
Embedded Operating Systems
12/107
gcc使用举例(2) 编译和运行
编译
运行
" 13."2019/11/1 Friday
Embedded Operating Systems
13/107
gcc的工作过程(1)
如果使用-v选项,则可以看到许多被隐藏的信息
" 14."2019/11/1 Friday
Embedded Operating Systems
14/107
" 15."2019/11/1 Friday
Embedded Operating Systems
15/107
gcc的编译过程
一般情况下,c程序的编译过程为
1、预处理
2、编译成汇编代码
3、汇编成目标代码
4、链接
" 16."2019/11/1 Friday
Embedded Operating Systems
16/107
1、预处理
预处理:使用-E参数 输出文件的后缀为“.cpp”
\t\tgcc –E –o gcctest.cpp gcctest.c
使用wc命令比较预处理后的文件与源文件,可以看到两个文件的差异
" 17."2019/11/1 Friday
Embedded Operating Systems
17/107
行数 单词数 字节数
预编译
" 18."2019/11/1 Friday
Embedded Operating Systems
18/107
预处理文件汇编代码 1)使用-x参数说明根据指定的步骤进行工作,cpp-output指明从预处理得到的文件开始编译 2)使用-S说明生成汇编代码后停止工作
gcc –x cpp-output –S –o gcctest.s gcctest.cpp
也可以直接编译到汇编代码
\tgcc –S gcctest.c
2、编译成汇编代码
" 19."2019/11/1 Friday
Embedded Operating Systems
19/107
预处理文件汇编代码
直接编译到汇编代码
s
" 20."2019/11/1 Friday
Embedded Operating Systems
20/107
3、编译成目标代码
汇编代码目标代码
\tgcc –x assembler –c gcctest.s
直接编译成目标代码
\tgcc –c gcctest.c
使用汇编器生成目标代码
as –o gcctest.o gcctest.s
" 21."2019/11/1 Friday
Embedded Operating Systems
21/107
汇编代码目标代码
直接编译成目标代码
使用汇编器
" 22."2019/11/1 Friday
Embedded Operating Systems
22/107
4、编译成执行代码
目标代码执行代码
\tgcc –o gcctest gcctest.o
直接生成执行代码
\tgcc –o gcctest gcctest.c
" 23."2019/11/1 Friday
Embedded Operating Systems
23/107
目标代码执行代码
直接生成执行代码
" 24."2019/11/1 Friday
Embedded Operating Systems
24/107
gcc的高级选项
-Wall:打开所有的警告信息
" 25."2019/11/1 Friday
Embedded Operating Systems
25/107
根据警告信息检查源程序
Main函数的返回值为int
在函数的末尾应当返回一个值
" 26."2019/11/1 Friday
Embedded Operating Systems
26/107
修改源程序
" 27."2019/11/1 Friday
Embedded Operating Systems
27/107
优化编译
优化编译选项有:
-O0 缺省情况,不优化
-O1
-O2
-O3
等等
不同程度的优化
" 28."2019/11/1 Friday
Embedded Operating Systems
28/107
gcc的优化编译举例(1) 考虑如下的源代码
不同的优化
编译选项
" 29."2019/11/1 Friday
Embedded Operating Systems
29/107
gcc的优化编译举例(2) 使用time命令统计程序的运行
" 30."2019/11/1 Friday
Embedded Operating Systems
30/107
二、GNU binutils
binutils是一组二进制工具程序集,是辅助GCC的主要软件,它主要包括
addr2line 把程序地址转换为文件名和行号。在命令行中给它一个地址和一个可执行文件名,它就会使用这个可执行文件的调试信息指出在给出的地址上是哪个文件以及行号。
ar 建立、修改、提取归档文件。归档文件是包含多个文件内容的一个大文件,其结构保证了可以恢复原始文件内容。
" 31."2019/11/1 Friday
Embedded Operating Systems
31/107
as 是GNU汇编器,主要用来编译GNU C编译器gcc输出的汇编文件,他将汇编代码转换成二进制代码,并存放到一个object文件中,该目标文件将由连接器ld连接
C filt解码C 符号名,连接器使用它来过滤 C 和 Java 符号,防止重载函数冲突。
gprof 显示程序调用段的各种数据。
ld 是连接器,它把一些目标和归档文件结合在一起,重定位数据,并链接符号引用,最终形成一个可执行文件。通常,建立一个新编译程序的最后一步就是调用ld。
" 32."2019/11/1 Friday
Embedded Operating Systems
32/107
nm 列出目标文件中的符号。
objcopy把一种目标文件中的内容复制到另一种类型的目标文件中.
objdump 显示一个或者更多目标文件的信息。使用选项来控制其显示的信息。它所显示的信息通常只有编写编译工具的人才感兴趣。
ranlib 产生归档文件索引,并将其保存到这个归档文件中。在索引中列出了归档文件各成员所定义的可重分配目标文件。
readelf 显示elf格式可执行文件的信息。
" 33."2019/11/1 Friday
Embedded Operating Systems
33/107
size 列出目标文件每一段的大小以及总体的大小。默认情况下,对于每个目标文件或者一个归档文件中的每个模块只产生一行输出。
strings 打印某个文件的可打印字符串,这些字符串最少4个字符长,也可以使用选项-n设置字符串的最小长度。默认情况下,它只打印目标文件初始化和可加载段中的可打印字符;对于其它类型的文件它打印整个文件的可打印字符,这个程序对于了解非文本文件的内容很有帮助。
strip 丢弃目标文件中的全部或者特定符号。
" 34."2019/11/1 Friday
Embedded Operating Systems
34/107
libiberty 包含许多GNU程序都会用到的函数,这些程序有: getopt 35. obstack 36. strerror 37. strtol 和 strtoul.
libbfd 二进制文件描述库.
libopcodes 用来处理opcodes的库 38. 在生成一些应用程序的时候也会用到它 39. 比如objdump.Opcodes是文本格式可读的处理器操作指令.
" 40."2019/11/1 Friday
Embedded Operating Systems
35/107
binutils开发工具使用举例
ar
nm
Objcopy
Objdump
readelf
" 41."2019/11/1 Friday
Embedded Operating Systems
36/107
1、ar
ar用于建立、修改、提取归档文件(archive),一个归档文件,是包含多个被包含文件的单个文件(也可以认为归档文件是一个库文件)。
被包含的原始文件的内容、权限、时间戳、所有者等属性都保存在归档文件中,并且在提取之后可以还原
" 42."2019/11/1 Friday
Embedded Operating Systems
37/107
使用ar建立库文件(1)
源程序add.c和minus.c
" 43."2019/11/1 Friday
Embedded Operating Systems
38/107
使用ar建立库文件(2)
编译成目标文件
将库文件拷贝到/usr/lib目录下
Ar的rv参数的说明:
\tr:将多个文件组成一个文件
\tv:输出信息
建立库文件
" 44."2019/11/1 Friday
Embedded Operating Systems
39/107
库文件使用举例 在代码中使用Add和Minus函数
" 45."2019/11/1 Friday
Embedded Operating Systems
40/107
在编译时指定库文件
指明将libtest.a链接进来
运行结果
" 46."2019/11/1 Friday
Embedded Operating Systems
41/107
2、nm
nm的主要功能是列出目标文件中的符号,这样程序员就可以定位和分析执行程序和目标文件中的符号信息和它的属性
" 47."2019/11/1 Friday
Embedded Operating Systems
42/107
nm显示的符号类型
A:符号的值是绝对值,并且不会被将来的链接所改变
B:符号位于未初始化数据部分(BSS段)
C:符号是公共的。公共符号是未初始化的数据。在链接时,多个公共符号可能以相同的名字出现。如果符号在其他地方被定义,则该文件中的这个符号会被当作引用来处理
D:符号位于已初始化的数据部分
T:符号位于代码部分
U:符号未被定义
?:符号类型未知,或者目标文件格式特殊\t
" 48."2019/11/1 Friday
Embedded Operating Systems
43/107
nm使用举例
如果对test可执行文件使用nm,
会有什么结果呢?(作业)
" 49."2019/11/1 Friday
Embedded Operating Systems
44/107
3、objcopy
可以将一种格式的目标文件内容进行转换,并输出为另一种格式的目标文件。
它使用GNU BFD(binary format description)库读/写目标文件,通过这个BFD库,objcopy能以一种不同于源目标文件的格式生成新的目标文件
$objcopy -h
在makefile里面用-O binary 选项来生成原始的二进制文件,即通常说的image文件
" 50."2019/11/1 Friday
Embedded Operating Systems
45/107
Objcopy使用举例
使用file命令查看文件类型
生成srec格式的目标文件
使用file命令查看新文件的类型
" 51."2019/11/1 Friday
Embedded Operating Systems
46/107
文件格式
a.out: assembler and link editor output 汇编器和链接编辑器的输出
coff common object file format 一种通用的对象文件格式
ELF excutive linked file Linux系统所采用的一种通用文件格式,支持动态连接。ELF格式可以比COFF格式包含更多的调试信息
" 52."2019/11/1 Friday
Embedded Operating Systems
47/107
文件格式
Flat elf格式有很大的文件头,flat文件对文件头和一些段信息做了简化 uClinux系统使用flat可执行文件格式
SREC MOTOROLA S-Recoder格式(S记录格式文件)
等等
" 53."2019/11/1 Friday
Embedded Operating Systems
48/107
4、objdump
显示一个或多个目标文件的信息,由其选项来控制显示哪些信息。
一般来说,objdump只对那些要编写编译工具的程序员有帮助,但是我们通过这个工具可以方便的查看执行文件或者库文件的信息
" 54."2019/11/1 Friday
Embedded Operating Systems
49/107
Objdump使用举例(1)
-f选项:显示文件头中的内容
" 55."2019/11/1 Friday
Embedded Operating Systems
50/107
Objdump使用举例(2)
-d选项进行反汇编
" 56."2019/11/1 Friday
Embedded Operating Systems
51/107
5、readelf
readelf: 显示一个或多个ELF格式的目标文件信息。
" 57."2019/11/1 Friday
Embedded Operating Systems
52/107
Readelf使用举例
" 58."2019/11/1 Friday
Embedded Operating Systems
53/107
三、其他GNU工具
Gdb—调试器
GNU make--软件工程工具
diff,patch--补丁工具
CVS--版本控制系统
" 59."2019/11/1 Friday
Embedded Operating Systems
54/107
1、GNU Toolchain—gdb
Gdb = GNU debuger
GNU tools中的调试器,功能强大
设置断点
监视、修改变量
单步执行
显示/修改寄存器的值
堆栈查看
远程调试
" 60."2019/11/1 Friday
Embedded Operating Systems
55/107
gdb使用举例
源代码如下
编译:
gcc –o bug bug.c
" 61."2019/11/1 Friday
Embedded Operating Systems
56/107
编译并运行
????
编译
" 62."2019/11/1 Friday
Embedded Operating Systems
57/107
使用gdb调试bug
运行bug
输入字符串hello
显示出错位置
能不能看到源代码呢?
" 63."2019/11/1 Friday
Embedded Operating Systems
58/107
使用gcc的-g参数
gcc –g –o bug bug.c
重新调试
列出源代码
" 64."2019/11/1 Friday
Embedded Operating Systems
59/107
?怎么修改前面的源代码呢?
设置断点
" 65."2019/11/1 Friday
Embedded Operating Systems
60/107
2、使用GNU make管理项目
GNU make是一种代码维护工具,在使用GNU编译器开发大型应用时,往往要使用make管理项目。
如果不使用make管理项目,就必须重复使用多个复杂的命令行维护项目和生成目标代码。
Make通过将命令行保存到makefile中简化了编译工作。
Make的主要任务是根据makefile中定义的规则和步骤,根据各个模块的更新情况,自动完成整个软件项目的维护和代码生成工作。
" 66."2019/11/1 Friday
Embedded Operating Systems
61/107
Make可以识别出makefile中哪些文件已经被修改,并且在再次编译的时候只编译这些文件,从而提高编译的效率
Make会检查文件的修改和生成时间戳,如果目标文件的修改或者生成时间戳比它的任意一个依赖文件旧,则make就执行makefile文件中描述的相应命令,以便更新目的文件
只更新那些需要更新的文件,而不重新处理那些并不过时的文件
" 67."2019/11/1 Friday
Embedded Operating Systems
62/107
特点:
适合于支持多文件构成的大中型软件项目的编译,链接,清除中间文件等管理工作
提供和识别多种默认规则,方便对大型软件项目的管理
支持对多目录的软件项目进行递归管理
对软件项目具有很好的可维护性和扩展性
" 68."2019/11/1 Friday
Embedded Operating Systems
63/107
makefile
Makefile告诉make该做什么、怎么做
makefile主要定义了
1)依赖关系 即有关哪些文件的最新版本是依赖于哪些别的文件产生或者组成的
2)需要用什么命令来产生目标文件的最新版本
3)以及一些其他的功能
" 69."2019/11/1 Friday
Embedded Operating Systems
64/107
Makefile的规则
规则 一条规则包含3个方面的内容,
1)要创建的目标(文件),
2)创建目标(文件)所依赖的文件列表;
3)通过依赖文件创建目标文件的命令组
" 70."2019/11/1 Friday
Embedded Operating Systems
65/107
规则一般形式
target ... : prerequisites ...
<tab>command
<tab>...
<tab>...
例如
test:test.c;gcc –O –o test test.c
" 71."2019/11/1 Friday
Embedded Operating Systems
66/107
一个简单的makefile
edit : main.o kbd.o command.o display.o insert.o search.o files.o utils.o
cc -o edit main.o kbd.o command.o display.o insert.o \\
\tsearch.o files.o utils.o
main.o : main.c defs.h
cc -c main.c
kbd.o : kbd.c defs.h command.h
cc -c kbd.c
command.o : command.c defs.h command.h
cc -c command.c
display.o : display.c defs.h buffer.h
cc -c display.c
insert.o : insert.c defs.h buffer.h
cc -c insert.c
search.o : search.c defs.h buffer.h
cc -c search.c
files.o : files.c defs.h buffer.h command.h
cc -c files.c
utils.o : utils.c defs.h
cc -c utils.c
clean :
\trm edit main.o kbd.o command.o display.o insert.o \\
\t\tsearch.o files.o utils.o
" 72."2019/11/1 Friday
Embedded Operating Systems
67/107
Make的工作过程
default goal 在缺省的情况下,make从makefile中的第一个目标开始执行
Make的工作过程类似一次深度优先遍历过程
" 73."2019/11/1 Friday
Embedded Operating Systems
68/107
Makefile 中的变量
使用变量可以
降低错误风险
简化makefile
例:objects变量($(objects))
objects = main.o kbd.o command.o \\
\t\tdisplay.o insert.o search.o files.o utils.o
edit : $(objects)
\t\tcc -o edit $(objects)
" 74."2019/11/1 Friday
Embedded Operating Systems
69/107
有点像环境变量
环境变量在make 过程中被解释成make的变量
可以被用来
贮存一个文件名列表。
贮存可执行文件名。如用变量代替编译器名。
贮存编译器FLAG
" 75."2019/11/1 Friday
Embedded Operating Systems
70/107
预定义变量
Make使用了许多预定义的变量,如
AR
AS
CC
CXX
CFLAGS
CPPFLAGS
等等
" 76."2019/11/1 Friday
Embedded Operating Systems
71/107
简化后的makefile文件
objects = main.o kbd.o command.o display.o \\
insert.o search.o files.o utils.o
edit : $(objects)
cc -o edit $(objects)
main.o : defs.h
kbd.o : defs.h command.h
command.o : defs.h command.h
display.o : defs.h buffer.h
insert.o : defs.h buffer.h
search.o : defs.h buffer.h
files.o : defs.h buffer.h command.h
utils.o : defs.h
.PHONY : clean
clean :
rm edit $(objects)
" 77."2019/11/1 Friday
Embedded Operating Systems
72/107
内部变量
$@扩展成当前规则的目的文件名
$<扩展成依赖列表中的第一个依赖文件
$^扩展成整个依赖列表(除掉了里面所有重复的文件名)
等等
不需要括号括住
例如: CC = gcc CFLAGS = -Wall -O -g foo.o : foo.c foo.h bar.h   $(CC) $(CFLAGS) -c $< -o $@
" 78."2019/11/1 Friday
Embedded Operating Systems
73/107
隐含规则 (Implicit Rules)
内置的规则
告诉make当没有给出某些命令的时候,应该怎么办。
用户可以使用预定义的变量改变隐含规则的工作方式,如
一个C编译的具体命令将会是:
$(CC) $(CFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c $< -o $@
" 79."2019/11/1 Friday
Embedded Operating Systems
74/107
设定目标(Phony Targets)
设定目标
目标不是一个文件
其目的是为了让一些命令得以执行
使用PHONY显式声明设定目标
.PHONY: clean
使用设定目标实现多个目的
all: prog1 prog2
" 80."2019/11/1 Friday
Embedded Operating Systems
75/107
典型的设定目标
设定目的也可以用来描述一些其他的动作。例如,想把中间文件和可执行文件删除,可以在 makefile 里设立这样一个规则: clean:
\t\t$rm *.o exec_file
前提是没有其它的规则依靠这个 'clean' 目的,它将永远不会被执行。但是,如果你明确的使用命令 'make clean' , make 会把这个目的做为它的主要目标,执行那些 rm 命令
" 81."2019/11/1 Friday
Embedded Operating Systems
76/107
Makefile中的函数 (Functions)
用来计算出要操作的文件、目标或者要执行的命令
使用方法:
$(function arguments)
典型的函数
$(subst from 82.to 83.text)
$(subst ee 84.EE 85.feet on the street)
相当于`fEEt on the strEEt'
" 86."2019/11/1 Friday
Embedded Operating Systems
77/107
$(patsubst pattern 87.replacement 88.text)
$(patsubst %.c 89.%.o 90.x.c.c bar.c)
相当于`x.c.o bar.o‘
$(wildcard pattern)
$(wildcard *.c)
objects := $(wildcard *.o)
" 91."2019/11/1 Friday
Embedded Operating Systems
78/107
makefile中的条件语句
conditional-directive
text-if-true
endif
or
conditional-directive
text-if-true
else
text-if-false
endif
" 92."2019/11/1 Friday
Embedded Operating Systems
79/107
四种条件语句
ifeq...else...endif
ifneq…else…endif
ifndef…else…endif
ifndef...else…endif
" 93."2019/11/1 Friday
Embedded Operating Systems
80/107
实际项目中的makefile
找到Linux或者uClinux源代码中所有的makefile,分析它们的功能、相互关系。
" 94."2019/11/1 Friday
Embedded Operating Systems
81/107
3、GNU Tools—ld
ld,The GNU Linker Linux上常用的链接器
ld软件的作用是把各种目标文件(.o文件)和库文件链接在一起,并定位数据和函数地址,最终生成可执行程序
gcc可以间接的调用ld,使用gcc的-Wl参数可以传递参数给ld
使用命令:ld --help可以列出ld常用的一些选项
" 95."2019/11/1 Friday
Embedded Operating Systems
82/107
ld使用举例(1)
源程序
编译hello.c到hello.o
命令:gcc -c hello.c
" 96."2019/11/1 Friday
Embedded Operating Systems
83/107
ld使用举例(2)
链接
命令:ld –dynamic-linker /lib/ld-linux.so.2 /usr/lib/crt1.o /usr/lib/crti.o /usr/lib/crtn.o hello.o –lc –o hello
运行
./hello
" 97."2019/11/1 Friday
Embedded Operating Systems
84/107
目标文件
ld通过BFD库可以读取和操作coff、elf、a.out等各种执行文件格式的目标文件
BFD(Binary File Descriptor)
目标文件(object file)
由多个节(section)组成,常见的节有:
text节保存了可执行代码,
data节保存了有初值的全局标量,
bss节保存了无初值的全局变量。
" 98."2019/11/1 Friday
Embedded Operating Systems
85/107
使用objdump查看目标文件的信息
objdump –h hello.o
比较hello
" 99."2019/11/1 Friday
Embedded Operating Systems
86/107
链接描述文件( Linker script )
可以使用链接描述文件控制ld的链接过程。
链接描述文件,command file 又称为链接脚本,Linker script
用来控制ld的链接过程
描述各输入文件的各节如何映射到输出文件的各节
控制输出文件中各个节或者符号的内存布局
使用的语言为:
The ld command language,链接命令语言
" 100."2019/11/1 Friday
Embedded Operating Systems
87/107
ld命令的-T commandfile选项指定了链接描述文件名
如果不指定链接描述文件,ld就会使用一个默认的描述文件来产生执行文件
找到Linux或者uClinux中的链接描述文件并分析。
" 101."2019/11/1 Friday
Embedded Operating Systems
88/107
链接描述文件的命令
链接描述文件的命令主要包括如下几类:
设置入口点命令
处理文件的命令
处理文件格式的命令
其他
" 102."2019/11/1 Friday
Embedded Operating Systems
89/107
常用的命令
设置入口点
格式:ENTRY(symbol) 设置symbol的值为执行程序的入口点。
ld有多种方法设置执行程序的入口点,确定程序入口点的顺序如下:
ld命令的-e选项指定的值
Entry(symbol)指定的值
.text节的起始地址
入口点为0
" 103."2019/11/1 Friday
Embedded Operating Systems
90/107
常用的命令
INCULDE filename 包含其他filename的链接描述文件
INPUT(file 104.file 105.…) 指定多个输入文件名
" 106."2019/11/1 Friday
Embedded Operating Systems
91/107
常用的命令
OUTPUT_FORMAT(bfdname) 指定输出文件的格式
OUTPUT_ARCH ( bfdname )
指定目标机器体系结构,例如: OUTPUT_ARCH(arm)
" 107."2019/11/1 Friday
Embedded Operating Systems
92/107
常用的命令
MEMORY: 这个命令在用于嵌入式系统的链接描述文件中经常出现,它描述了各个内存块的起始地址和大小。格式如下:
MEMORY
{
\tname [(attr)

查看更多