139
第5第 TMS320C54x 第第第第 5.1 第第第第第第第第第第第 5.2 第第第第第第第第 5.3 第第第第第第第 5.4 第第第第第第第第第第第第第 5.5 第第第第第第第第第第 5.6 TMS320C54x C 第第第第 5.7 C 第第第第第第第第第第第

第5章 TMS320C54x 软件开发

Embed Size (px)

DESCRIPTION

第5章 TMS320C54x 软件开发. 5.1 软件开发过程及开发工具 5.2 公共目标文件格式 5.3 常用汇编伪指令 5.4 链接器命令文件的编写与使用 5.5 汇编语言程序编写方法 5.6 TMS320C54x C 语言编程 5.7 用 C 语言和汇编语言混合编程. 5.1 软件开发过程及开发工具. 1 .建立源程序 2 . C 编译器( C Compiler ) 3 .汇编器( Assembler ) 4 .连接器( Linker ) 5 .调试工具 6 .十六进制转换公用程序( Hex Conversion Utility ). - PowerPoint PPT Presentation

Citation preview

Page 1: 第5章   TMS320C54x 软件开发

第 5 章 TMS320C54x 软件开发 5.1 软件开发过程及开发工具 5.2 公共目标文件格式 5.3 常用汇编伪指令 5.4 链接器命令文件的编写与使用 5.5 汇编语言程序编写方法 5.6 TMS320C54x C语言编程 5.7 用C语言和汇编语言混合编程

Page 2: 第5章   TMS320C54x 软件开发

5.1 软件开发过程及开发工具1 .建立源程序2 . C 编译器( C Compiler )

3 .汇编器( Assembler )

4 .连接器( Linker )

5 .调试工具6 .十六进制转换公用程序( Hex Conversion

Utility )

返回首页

Page 3: 第5章   TMS320C54x 软件开发

图 5-1 TMS320C54x DSP 软件开发流程( 1 )

Page 4: 第5章   TMS320C54x 软件开发

C 源文件

C 编译器

汇编源文件汇编器

汇编源文件

COFF目标文件

链接器

可执行的COFF 文件

宏源文件

存档器

宏库

存档器

目标文件库

建库工具

运行时支持库

EPROM编程器 交叉引用列表器

调试工具

TMS320C54x

绝对地址列表器

HEX 代码转换工具

图 5-1 TMS320C54x DSP 软件开发流程( 2 )

Page 5: 第5章   TMS320C54x 软件开发

C 编译器:用来将 C/C++ 语言源程序自动编译为’ C54x 的汇编语言源程序。 汇编器:用来将汇编语言源文件汇编成机器语言COFF 目标文件。 链接器:将汇编生成的、可重新定位的 COFF 目标模块组合成一个可执行的 COFF 目标模块。 归档器:允许用户将一组文件(源文件或目标文件)集中为一个文档文件库。 交叉引用列表器:利用目标文件生成一个交叉引用清单,列出链接的源文件中的符号以及它们的定义和引用情况。

Page 6: 第5章   TMS320C54x 软件开发

汇编器汇编器 调试程序调试程序链接器链接器文本编辑器文本编辑器.asm源文件 .obj目标文件 .out输出文件

. cmd链接命令文件

. lst列表文件. map存储器映像文件

十六进制十六进制转换程序转换程序HEX500HEX500

- o- m- l

Page 7: 第5章   TMS320C54x 软件开发

调试工具 软件仿真器:是一种模拟 DSP 芯片各种功能并在非实时条件下进行软件调试的调试工具,它不需目标硬件支持,只需在计算机上运行。 硬件仿真器:可扩展的开发系统仿真器 (XDS510) ,可用来进行系统级的实时集成调试,是进行 DSP 芯片软硬件开发的最佳工具。 评价模块 EVM 板:是一种低成本的开发板,可进行 DSP 芯片评价、性能评估和有限的系统调试。

Page 8: 第5章   TMS320C54x 软件开发

表 5-1 TMS320C54xV3.50 版代码生成工具程序

返回本节

Page 9: 第5章   TMS320C54x 软件开发

用 C/C++ 语言或汇编语言编写源文件,经 C 编译器、汇编器生成 COFF 格式的目标文件,再用链接器进行链接,生成在 C54x 上可执行的目标代码,然后利用调试工具对可执行的目标代码进行仿真和调试。当调试完成后,通过 Hex 代码转换工具,将调试后的可执行目标代码转换成 EPROM 编程器能接受的代码,并将该代码固化到 EPROM 中或加载到用户的应用系统中,以便 DSP 目标系统脱离计算机单独运行。

十六进制转换程序

Page 10: 第5章   TMS320C54x 软件开发

5.2 公共目标文件格式 5.2.1 COFF文件的基本单元——段 5.2.2 汇编器对段的处理 5.2.3 链接器对段的处理 5.2.4 重新定位 5.2.5 程序装入 5.2.6 COFF文件中的符号

返回首页

Page 11: 第5章   TMS320C54x 软件开发

5.2.1 COFF 文件的基本单元——段 段( sections )是 COFF 文件中最重要的概念。一个段就是最终在存储器映象中占据连续空间的一个数据或代码块。目标文件中的每一个段都是相互独立的。一般地, COFF 目标文件包含 3 个缺省的段: text 段、 data 段、 bss 段。 段可以分为两大类,即已初始化段和未初始化段。如图 5-2 所示为目标文件中的段与目标系统中存储器的关系。

Page 12: 第5章   TMS320C54x 软件开发

图 5-2 目标文件中的段与目标存储器的关系

返回本节

Page 13: 第5章   TMS320C54x 软件开发

5.2.2 汇编器对段的处理1 .未初始化段 未初始化段主要用来在存储器中保留空间,通常将它们定位到 RAM 中。这些段在目标文件中没有实际内容,只是保留空间而已。程序可以在运行时利用这些空间建立和存储变量。未初始化段是通过使用 .bss 和 .usect 汇编伪指令建立的,两条伪指令的句法分别为:

.bss 符号,字数 符号 .usect“ 段名”,字数

Page 14: 第5章   TMS320C54x 软件开发

2 .已初始化段 已初始化段包含可执行代码或已初始化数据。这些段的内容存储在目标文件中,加载程序时再放

到 TMS320C54X 存储器中。三个用于建立初始化段的伪指令句法分别为: .text[ 段起点 ] .data [ 段起点 ] .sect “ 段名” [ ,段起点 ]

Page 15: 第5章   TMS320C54x 软件开发

3 .命名段 命名段就是程序员自己定义的段,它与缺省的 .text 、 .data 和 .bss 段一样使用,但与缺省段分开汇编。 data 段不同的存储器中,将未初始化的变量汇编到与. bss 段不同的存储器中。产生命名段的伪指令为: 符号 .usect “ 段名”,字数 .sect “ 段名” [ ,段起点 ]

Page 16: 第5章   TMS320C54x 软件开发

4 .子段 子段( Subsections )是大段中的小段。链接器可以像处理段一样处理子段。采用子段可以使存储器图更加紧密。子段的命名句法为:

基段名:子段名 子段也有两种,用 .sect 命令建立的是已初始化段,用 .usect 命令建立的是未初始化段。 例如,若要在例如,若要在 ..texttext 段内建立一个称之为段内建立一个称之为 __funcfunc的子段,其命令格式:的子段,其命令格式:

..sect “.textsect “.text :: _func”_func”

Page 17: 第5章   TMS320C54x 软件开发

5 .段程序计数器( SPC ) 汇编器为每个段安排一个独立的程序计数器,即段程序计数器( SPC )。 SPC 表示一个程序代码段或数据段内的当前地址。开始时,汇编器将每个 SPC置 0 ,当汇编器将程序代码或数据加到一个段内时,相应的 SPC增加。如果汇编器再次遇到相同段名的段,继续汇编至相应的段,且相应的 SPC 在先前的基础上继续增加。

Page 18: 第5章   TMS320C54x 软件开发

段命令应用举例段命令应用举例【【例例 5-15-1】】段命令应用举例。段命令应用举例。 汇编语言源程序:汇编语言源程序: ..datadatacoeff .word coeff .word 044h,055h,066h044h,055h,066h ..bss bufferbss buffer ,, 8 8 prt .word 0456hprt .word 0456h ..texttextaddadd : : LD 0DhLD 0Dh ,, A A aloopaloop :: SUB #1SUB #1 ,, A A BC aloopBC aloop ,, AGEQAGEQ ..datadataivals .word ivals .word 0CCh0CCh ,, 0DDh0DDh ,, 0EEh0EEh

;; 初始化数据段初始化数据段 ;3;3 组数据放入组数据放入 ..datadata 段段 ;; 在在 ..bssbss 段保留段保留 88 个单元个单元 ;0456h;0456h 放入放入 ..datadata 段段 ;; 初始化文本段初始化文本段 ;1;1 字指令字指令 ;2;2 字指令字指令 ;2;2 字指令字指令

共计 5个字 ;; 初始化数据段初始化数据段 ;3;3 组数据放入组数据放入 ..datadata 段段

Page 19: 第5章   TMS320C54x 软件开发

段命令应用举例段命令应用举例汇编语言源程序:汇编语言源程序:var2 .usect “newvars”var2 .usect “newvars” ,, 2 2 inbuf .usect “newvars”inbuf .usect “newvars” ,, 88 .text.text mpympy :: LD 0AhLD 0Ah ,, BB mloopmloop :: MPY #0AhMPY #0Ah ,, BB BC mloopBC mloop ,, BNOVBNOV .sect “vectors” .sect “vectors” .word 044h.word 044h ,, 088h 088h

;; 建立建立 newvarsnewvars 命名段命名段 ,, 保留保留 22 个单个单元元 ;; 在在 newvarsnewvars 段保留段保留 88 个单元个单元 ;; 初始化文本段初始化文本段 ;1;1 字指令字指令 ;2;2 字指令字指令 ;2;2 字指令字指令

共计 5个字

;; 建立建立 vectorsvectors 命名段命名段 ;2;2 组数据放入组数据放入 vectorsvectors 命名段命名段

Page 20: 第5章   TMS320C54x 软件开发

段命令应用举例段命令应用举例经汇编后,得列表文件(部分): 经汇编后,得列表文件(部分):

22 ********************************** **********************************33 ** ** 汇编一个初始化表到汇编一个初始化表到 ..datadata 段段 ****44 ********************************************************************55 00000000 .data .data66 00000000 00440044 coeff .word 044h,055h,066h coeff .word 044h,055h,066h 0001 0001 00550055 0002 0002 0066006677 ********************************** **********************************88 ** ** 在在 ..bssbss 段中为变量保留空间段中为变量保留空间 ****99 ********************************** **********************************1010 00000000 .bss buffer .bss buffer ,, 881111 ********************************** **********************************1212 ** ** 仍然在仍然在 ..data data 段中段中 ****1313 ********************************** **********************************1414 0003 0003 04560456 prt prt ..word 0456hword 0456h

Page 21: 第5章   TMS320C54x 软件开发

段命令应用举例段命令应用举例1515 ********************************** **********************************1616 ** ** 汇编代码到汇编代码到 ..texttext 段段 ****1717 ********************************** **********************************1818 00000000 .text .text1919 00000000 100d 100d add add :: LD 0DhLD 0Dh ,, AA2020 00010001 f010f010 aloop aloop : : SUB #1SUB #1 , , AA 00020002 00010001 2121 0003 0003 f842f842 BC aloopBC aloop ,, AGEQAGEQ 00040004 0001’0001’ 2222 ********************************************************************2323 ** ** 汇编另一个初始化表到汇编另一个初始化表到 ..data data 段段 **** 24 24 ********************************** **********************************2525 00040004 ..datadata 2626 00040004 00cc00cc ivals ivals . .word 0CChword 0CCh ,, 0DDh0DDh ,, 0EEh 0EEh 0005 0005 00dd00dd 00060006 00ee00ee2727 ********************************** **********************************2828 ** ** 为更多的变量定义另一个段为更多的变量定义另一个段 ****2929 ********************************** **********************************3030 00000000 var2 var2 ..usect “newvars”usect “newvars” ,, 2 2 31 31 00010001 inbuf inbuf . .usect “newvars”usect “newvars” ,, 88

Page 22: 第5章   TMS320C54x 软件开发

段命令应用举例段命令应用举例3232 ********************************** **********************************************3333 ** ** 汇编更多代码到汇编更多代码到 ..texttext 段段 ****3434 **************************************** ****************************************3535 00050005 ..texttext 3636 0005 0005 110a110a mpympy :: LD 0AhLD 0Ah ,, BB 37 37 00060006 f166f166 mloop MPY #0Ah mloop MPY #0Ah ,, B B 00070007 000a000a 3838 0008 0008 f868 f868 BC mloop BC mloop ,, BNOV BNOV 00090009 0006’0006’ 3939 **************************************** ****************************************4040 ** ** 为中断向量为中断向量 ..vectorsvectors 定义一个自定义段 定义一个自定义段 ** ** 4141 **************************************** ****************************************4242 00000000 ..sect “vectors” sect “vectors” 43 43 00000000 00440044 ..word 044hword 044h ,, 088h088h 00010001 00880088

源程序的行号 段程序计数器 目标代码 汇编语言源程序

Page 23: 第5章   TMS320C54x 软件开发

段命令应用举例段命令应用举例 汇编语言源程序经过汇编后,共建立了汇编语言源程序经过汇编后,共建立了 55 个段:个段: ●● .text.text 段段——文本段,段内有——文本段,段内有 1010个字可执行个字可执行 的程序代码。的程序代码。 ●● ..datadata 段段——已初始化的数据段,段内有——已初始化的数据段,段内有 77 个字的数据。个字的数据。 ●● vectorsvectors 段段————用用 ..sectsect 命令生成的命名段命令生成的命名段 , , 段内有段内有 22 个字的初始化数据。个字的初始化数据。 ●● ..bssbss 段段——未初始化的数据段,——未初始化的数据段,在存储器中在存储器中 为变量保留为变量保留 88个存储单元。个存储单元。 ●● newvarsnewvars 段段——用——用 ..usectusect 命令建立的命名段命令建立的命名段 , , 为变量保留为变量保留 1010个存储单元。个存储单元。

Page 24: 第5章   TMS320C54x 软件开发

段命令应用举例段命令应用举例经汇编后,得列表文件(部分): 经汇编后,得列表文件(部分): 22 ******************************* *******************************33 ** ** 汇编一个初始化表到汇编一个初始化表到 ..datadata 段段 ****44 **************************************************************55 00000000 .data .data66 00000000 00440044 coeff .word 044h,055h,066h coeff .word 044h,055h,066h 0001 0001 00550055 0002 0002 0066006677 ******************************* *******************************88 ** ** 在在 ..bssbss 段中为变量保留空间段中为变量保留空间 ****99 ******************************* *******************************1010 00000000 .bss buffer .bss buffer ,, 881111 ******************************* *******************************1212 ** ** 仍然在仍然在 ..data data 段中段中 ****1313 ******************************* *******************************1414 0003 0003 04560456 prt prt ..word 0456hword 0456h

行号 目标代码 段名100df0100001f8420001110af166000aF8680006

004400550066045600cc00dd00ee

00440088

没有数据保留 10 个字

5 5 0000 .data0000 .data6 0000 0044 coeff .word 044h,055h,066h6 0000 0044 coeff .word 044h,055h,066h

10 0000 .bss buffer10 0000 .bss buffer ,, 88

14 0003 0456 prt 14 0003 0456 prt ..word 0456hword 0456h

..datadata 66 0044004466 0055005566 00660066

1010 ..bssbss 没有数据没有数据保留保留 88 个字个字

1414 04560456

Page 25: 第5章   TMS320C54x 软件开发

段命令应用举例段命令应用举例1515 ******************************** ********************************1616 ** ** 汇编代码到汇编代码到 ..texttext 段段 ****1717 ******************************** ********************************1818 00000000 .text .text1919 00000000 100d 100d add add :: LD 0DhLD 0Dh ,, AA2020 00010001 f010f010 aloop aloop : : SUB #1SUB #1 , , AA 00020002 00010001 2121 0003 0003 f842f842 BC aloopBC aloop ,, AGEQAGEQ 00040004 0001’0001’ 2222 ********************************************************************2323 ** ** 汇编另一个初始化表到汇编另一个初始化表到 ..data data 段段 **** 2424 ********************************** **********************************2525 00040004 ..datadata 2626 00040004 00cc00cc ivals ivals ..word word

0CCh0CCh ,, 0DDh0DDh ,, 0EEh 0EEh 0005 0005 00dd00dd 00060006 00ee00ee2727 ******************************** ********************************2828 ** ** 为更多的变量定义另一个段为更多的变量定义另一个段 ****2929 ******************************** ********************************3030 00000000 var2 var2 ..usect “newvars”usect “newvars” ,, 2 2 3131 00010001 inbuf inbuf . .usect “newvars”usect “newvars” ,, 88

行号 目标代码 段名100df0100001f8420001110af166000aF8680006

66614004400550066045600cc00dd00ee

.data

00440088

10 没有数据保留 8个字 .bss

没有数据保留 10 个字

..texttext

18 0000 .text18 0000 .text19 0000 100d add19 0000 100d add :: LD 0DhLD 0Dh ,, AA

1919 100d100d

20 0001 f010 aloop20 0001 f010 aloop : : SUB #1SUB #1 , , AA

2020 f010f0102020 00010001

21 21 0003 0003 f842 BC aloopf842 BC aloop ,, AGEQAGEQ

2121 f842f8422121 00010001

25 0004 25 0004 . .datadata26 0004 00cc ivals 26 0004 00cc ivals ..word word

0CCh0CCh ,, 0DDh0DDh ,, 0EEh0EEh

..datadata

2626 00cc00cc2626 00dd00dd2626 00ee00ee

30 0000 var2 30 0000 var2 ..usect “newvars”usect “newvars” ,, 22 newvanewvarsrs

3030 保留保留 22 个字个字31 0001 inbuf 31 0001 inbuf . .usect “newvars”usect “newvars” ,, 88 3131 保留保留 88 个字个字

Page 26: 第5章   TMS320C54x 软件开发

段命令应用举例段命令应用举例3232 *********************** *******************************************3333 ** ** 汇编更多代码到汇编更多代码到 ..texttext 段段 ****3434 ********************************* *********************************3535 00050005 ..texttext 3636 0005 0005 110a110a mpympy :: LD 0AhLD 0Ah ,, BB 37 37 00060006 f166f166 mloop MPY #0Ah mloop MPY #0Ah ,, B B 00070007 000a000a 3838 0008 0008 f868 f868 BC mloop BC mloop ,, BNOV BNOV 00090009 0006’0006’ 3939 **************************************** ****************************************4040 ** ** 为中断向量为中断向量 ..vectorsvectors 定义一个自定义段 定义一个自定义段 ** ** 4141 **************************************** ****************************************4242 00000000 ..sect “vectors” sect “vectors” 43 43 00000000 00440044 ..word 044hword 044h ,, 088h088h 00010001 00880088

行号 目标代码 段名1920202121

100df0100001f8420001110af166000aF8680006

.text

66614262626

004400550066045600cc00dd00ee

.data

00440088

10 没有数据保留 8个字 .bss

3031 没有数据保留 10个字 newvars

35 0005 35 0005 ..texttext

..texttext

36 0005 110a mpy36 0005 110a mpy :: LD 0AhLD 0Ah ,, B B 3636 110a110a

37 37 0006 f166 mloop MPY #0Ah0006 f166 mloop MPY #0Ah ,, BB3737 f168f1683737 000a000a

38 0008 f868 BC mloop38 0008 f868 BC mloop ,, BNOVBNOV3838 f868f8683838 00060006

42 0000 42 0000 ..sect “vectors”sect “vectors” vectorvectorss 43 0000 0044 43 0000 0044 . .word 044hword 044h ,, 088h088h 44

33 00440044

4433 00880088

Page 27: 第5章   TMS320C54x 软件开发

5.2.35.2.3 链接器对段的处理 链接器对段的处理 链接器是开发链接器是开发’’ C54xC54x 器件必不可少的开发工具器件必不可少的开发工具之一,它对段处理时有之一,它对段处理时有 22 个主要任务:个主要任务: ①① 将一个或多个将一个或多个 COFFCOFF 目标文件(目标文件( ..objobj 文件)文件)中的各种段作为链接器的输入段,经链接后在一个中的各种段作为链接器的输入段,经链接后在一个执行的执行的 COFFCOFF 输出模块中建立各个输出段;输出模块中建立各个输出段; ②② 在程序装入时对其重新定位,在程序装入时对其重新定位,为各个输出段选为各个输出段选定存储器地址。定存储器地址。

Page 28: 第5章   TMS320C54x 软件开发

链接器有链接器有 22 条伪指令支持上述任务:条伪指令支持上述任务: ●● MEMORYMEMORY 伪指令伪指令——用来定义目标系统的存——用来定义目标系统的存储器配置空间,包括对存储器各部分命名,以及规储器配置空间,包括对存储器各部分命名,以及规定它们的起始地址和长度。定它们的起始地址和长度。 ●● SECTIONSSECTIONS 伪指令伪指令——用来指定链接器将输——用来指定链接器将输入段组合成输出段方式,以及输出段在存储器中的入段组合成输出段方式,以及输出段在存储器中的位置,也可用于指定子段。位置,也可用于指定子段。 若未使用伪指令,则链接器将使用目标处理器默若未使用伪指令,则链接器将使用目标处理器默认的方法将段放入存储空间。认的方法将段放入存储空间。

Page 29: 第5章   TMS320C54x 软件开发

一、默认的存储器分配一、默认的存储器分配 链接器可对多个目标文件进行链接。若链接文件中链接器可对多个目标文件进行链接。若链接文件中不使用不使用 MEMORYMEMORY 和和 SECTIONSSECTIONS 命令,则为默认命令,则为默认方式。方式。 每个目标文件都有每个目标文件都有 ..texttext ,, .data.data 、、 ..bssbss 段和段和命名段。若采用默认链接,链接器将对多个目标文件命名段。若采用默认链接,链接器将对多个目标文件中的各个段进行组合,形成各自的对应段,并将各个中的各个段进行组合,形成各自的对应段,并将各个段配置到所指定的存储器中,形成可执行的目标模块段配置到所指定的存储器中,形成可执行的目标模块。。 在默认的方式下,链接器将从存储器的在默认的方式下,链接器将从存储器的 00800080hh 开开始,对组合后的各段进行存储器配置。始,对组合后的各段进行存储器配置。

Page 30: 第5章   TMS320C54x 软件开发

默认的存储器分配方法:默认的存储器分配方法: ① ① 将所有将所有 ..texttext 段组合在一起,形成一个段组合在一起,形成一个 ..texttext段,并分配到程序存储器中;段,并分配到程序存储器中; ② ② 将多个目标文件中的将多个目标文件中的 ..datadata 段组合在一起,分段组合在一起,分配到紧接着配到紧接着 ..texttext 段的程序存储空间中;段的程序存储空间中; ③ ③ 将将 ..bssbss 段组合,配置到数据存储器中;段组合,配置到数据存储器中; ④ ④ 组合命名段。初始化的命名段按顺序分配到紧组合命名段。初始化的命名段按顺序分配到紧随随 ..datadata 段的程序存储器,而未初始化命名段将被段的程序存储器,而未初始化命名段将被配置到紧随配置到紧随 ..bssbss 段的数据存储器中。段的数据存储器中。

Page 31: 第5章   TMS320C54x 软件开发

默认的存储器分配过程:默认的存储器分配过程:File1.obj

.text1

.data1

.bss1table_1

( 初始化的命名段 )

u_vars1 ( 未初始化的命名段 )

File2.obj

.text2

.data2

.bss2table_2

( 初始化的命名段 )

u_vars2 ( 未初始化的命名段 )

FFT( 初始化的命名段 )

程序存储器 数据存储器.text.text ..text1text1

..text2text2

.data.data ..data1data1..data2data2 .bss.bss..bss1bss1

..bss2bss2

tabletabletable_1table_1

table_2table_2 u_varsu_vars11

u_vars1u_vars1

u_vars2u_vars2FFTFFT FFTFFT

没有使用没有使用

没有配置没有配置

没有配置没有配置

没有使用没有使用

Page 32: 第5章   TMS320C54x 软件开发

二、段放入存储器空间二、段放入存储器空间 若不希望链接器将所有的若不希望链接器将所有的 ..texttext 段结合在一起形成段结合在一起形成单个的单个的 ..texttext 段,就不能采用默认的方式。段,就不能采用默认的方式。 由于由于 DSPDSP 硬件系统中可能配置多种类型的存储器硬件系统中可能配置多种类型的存储器 ,,若要把某一段分配到特定类型的存储器中,或将命名若要把某一段分配到特定类型的存储器中,或将命名段配置特定的地址,则需采用段配置特定的地址,则需采用 MEMORYMEMORY 和和SECTIONSSECTIONS 伪指令来配置。伪指令来配置。 若不采用默认的方式,通常需要建立一个链接命令若不采用默认的方式,通常需要建立一个链接命令文件,在命令文件中用文件,在命令文件中用 MEMORYMEMORY 和和 SECTIONSSECTIONS伪指令定义存储器和配置段地址。伪指令定义存储器和配置段地址。

Page 33: 第5章   TMS320C54x 软件开发

5.2.45.2.4 链接器对程序的重新定位 链接器对程序的重新定位 1.1. 链接器重新定位 链接器重新定位 汇编器对每个段汇编时都是从汇编器对每个段汇编时都是从 00 地址开始,而所地址开始,而所有需要重新定位的符号有需要重新定位的符号 ((标号标号 ))在段内都是相对于在段内都是相对于 00

地址的。事实上,所有段都不可能从存储器中地址的。事实上,所有段都不可能从存储器中 00 地地址单元开始,因此链接器必须对各个段进行重新定址单元开始,因此链接器必须对各个段进行重新定位。位。

重新定位的方法:重新定位的方法: 将各个段配置到存储器中,使每个段都有一个将各个段配置到存储器中,使每个段都有一个 合适的起始地址;合适的起始地址; 将符号变量调整到相对于新的段地址的位置;将符号变量调整到相对于新的段地址的位置; 将引用调整到重新定位后的符号,这些符号将引用调整到重新定位后的符号,这些符号 反映了调整后的新符号值。反映了调整后的新符号值。

Page 34: 第5章   TMS320C54x 软件开发

1.1. 链接器重新定位 链接器重新定位 汇编器在需要引用重新定位的符号处都留了一个汇编器在需要引用重新定位的符号处都留了一个重定位入口。链接器在对符号重新定位时,利用这重定位入口。链接器在对符号重新定位时,利用这些入口修正对符号的引用值。些入口修正对符号的引用值。

【例【例 4.3.24.3.2】】一段采用助记符指令编写的程序,经汇编后得一段采用助记符指令编写的程序,经汇编后得列表文件如下:列表文件如下:

11 . . ref Xref X22 . ref Z. ref Z33 00000000 . text. text44 00000000 F073F073 B YB Y ;;产生一个重定位入口产生一个重定位入口 00010001 0006’0006’55 00020002 F073F073 B ZB Z ;;产生一个重定位入口产生一个重定位入口 00030003 00000000 !!66 00040004 F020F020 LD #XLD #X ,, AA ;;产生一个重定位入口产生一个重定位入口 00050005 00000000 !!77 00060006 F7E0F7E0 YY : : RESETRESET

Page 35: 第5章   TMS320C54x 软件开发

程序中有三个符号:程序中有三个符号: XX 、、 Z——Z—— 是在另一个模块中定义的; 是在另一个模块中定义的; Y——Y—— 在在 ..texttext 段中定义的。 段中定义的。 当程序汇编时,当程序汇编时, XX 、、 ZZ 的值为的值为 0——0—— 未定义的外部符号未定义的外部符号 YY 的值为的值为 66———— 相对于相对于 ..texttext 段地址段地址 00定义定义 汇编器形成了两个重定位入口:汇编器形成了两个重定位入口: XX 和和 ZZ ::在在 ..texttext 段中为一次外部引用,用符号!表示段中为一次外部引用,用符号!表示;; YY ::是一次内部引用,用符号’表示是一次内部引用,用符号’表示 。 。 假设假设链接时,链接时, XX 重新定位在地址重新定位在地址 71007100hh ..texttext 段起始地址重新定位在段起始地址重新定位在 72007200hh

Page 36: 第5章   TMS320C54x 软件开发

链接器利用两个重定位入口,对目标文件中的两次引用进链接器利用两个重定位入口,对目标文件中的两次引用进行修正:行修正:变成变成 f073f073 72067206’’变成变成 f020f020 71007100!!

f073f073 B YB Y 0006’0006’ f020f020 LD #XLD #X ,, AA 0000!0000!

Page 37: 第5章   TMS320C54x 软件开发

2.2. 运行时重新定位 运行时重新定位 在实际运行中,有时需要将代码装入存储器的一个在实际运行中,有时需要将代码装入存储器的一个地方,而在另一个地方运行。地方,而在另一个地方运行。 如:一些关键的执行代码必须装在系统的如:一些关键的执行代码必须装在系统的 ROMROM 中中,, 但运行时希望在较快的但运行时希望在较快的 RAMRAM 中进行。中进行。 利用利用 SECTIONSSECTIONS 伪指令选项可让链接器对其定位伪指令选项可让链接器对其定位22次,其方法:次,其方法: ① ① 使用装入关键字设置装入地址;使用装入关键字设置装入地址; ② ② 使用运行关键字设置它的运行地址。使用运行关键字设置它的运行地址。

Page 38: 第5章   TMS320C54x 软件开发

装入地址确定段的原始数据或代码装入的位置,而装入地址确定段的原始数据或代码装入的位置,而任何对段的使用(例如其中的标号),则参考它的运任何对段的使用(例如其中的标号),则参考它的运行地址。在应用中必须将该段从装入地址复制到运行行地址。在应用中必须将该段从装入地址复制到运行地址。地址。 如果只为段提供了一次定位(装入或运行),则该如果只为段提供了一次定位(装入或运行),则该段将只定位一次,并且装入和运行地址相同。如果提段将只定位一次,并且装入和运行地址相同。如果提供了供了 22 个地址,则段将被自动定位。 个地址,则段将被自动定位。

Page 39: 第5章   TMS320C54x 软件开发

5.2.5 5.2.5 程序装入程序装入 链接器产生可执行的链接器产生可执行的 COFFCOFF 目标文件。可执行的目标文件。可执行的目标文件模块与链接器输入的目标文件具有相同的目标文件模块与链接器输入的目标文件具有相同的COFFCOFF 格式。为了运行程序,在可执行模块中的数格式。为了运行程序,在可执行模块中的数据必须传输或装入目标系统存储器中。据必须传输或装入目标系统存储器中。

可以采用以下方法装入程序:可以采用以下方法装入程序: 使用调试工具转入程序使用调试工具转入程序 ’ ’C54xC54x 的调试工具包括软件模拟器,的调试工具包括软件模拟器, XDSXDS 仿真仿真器和集成系统器和集成系统 CCSCCS 。。它们都具有内部的装入器,调它们都具有内部的装入器,调用装入器的用装入器的 LOADLOAD 命令,装入器将程序复制到目标命令,装入器将程序复制到目标系统的存储器中。 系统的存储器中。 采用采用 HexHex 转换工具转入程序转换工具转入程序 可以使用转换工具可以使用转换工具 Hex500Hex500 ,,将可执行将可执行 COFFCOFF目标模块转换成几种其他目标格式文件,然后将转目标模块转换成几种其他目标格式文件,然后将转换后的文件通过编程器将程序装(烧)进换后的文件通过编程器将程序装(烧)进EPROMEPROM 。。

Page 40: 第5章   TMS320C54x 软件开发

5.2.65.2.6 COFFCOFF 文件中的符号 文件中的符号 COFFCOFF 文件中有一个符号表,主要用来存储程序文件中有一个符号表,主要用来存储程序中有关符号的信息。链接器在执行程序定位时,要中有关符号的信息。链接器在执行程序定位时,要使用符号表提供的信息,而调试工具也要使用该表使用符号表提供的信息,而调试工具也要使用该表来提供符号调试。来提供符号调试。

1.1. 外部符号外部符号 是指在一个模块中定义、而在另一个模块中引用是指在一个模块中定义、而在另一个模块中引用的符号。它可以用伪指令的符号。它可以用伪指令 ..defdef 、、 ..refref 或或 ..globalglobal来定义。来定义。 ●●..defdef 在当前模块中定义,并可在别的模块中在当前模块中定义,并可在别的模块中使用的符号;使用的符号; ●●..ref ref 在当前模块中使用,但在别的模块中定在当前模块中使用,但在别的模块中定义的符号;义的符号; ●●..globalglobal 可以是上面的任何一种情况。可以是上面的任何一种情况。

Page 41: 第5章   TMS320C54x 软件开发

【例【例 5-35-3】】说明代码段中外部符号的定义。说明代码段中外部符号的定义。 xx : : ADD ADD #56h#56h ,, AA B yB y .def x.def x ..ref yref y

;; 定义定义 xx

;; 引用引用 yy

;;xx 在此模块中定义,可为别在此模块中定义,可为别 的模块引用的模块引用 ;;yy 在这里引用,它在别的模在这里引用,它在别的模 块中定义块中定义

Page 42: 第5章   TMS320C54x 软件开发

2.2. 符号表 符号表 每当遇到一个外部符号,无论是定义的还是引用每当遇到一个外部符号,无论是定义的还是引用的,汇编器都将在符号表中产生一个条目。的,汇编器都将在符号表中产生一个条目。 汇编器还产生一个指到每段的专门符号,链接器汇编器还产生一个指到每段的专门符号,链接器使用这些符号将其他引用符号重新定位。使用这些符号将其他引用符号重新定位。

Page 43: 第5章   TMS320C54x 软件开发

5.3 常用汇编伪指令

返回首页

表 5-2 常用的汇编伪指令

Page 44: 第5章   TMS320C54x 软件开发

1 .段定义伪指令 为便于链接器将程序、数据分段定位于指定的(物理存在的)存储器空间,并将不同的 obj 文件链接起来。段的使用非常灵活,但常用以下约定: .text — 此段存放程序代码。 .data — 此段存放初始化了的数据。 .bss — 此段存入未初始化的变量。 .sect ‘ 名称’ — 定义一个有名段,放初始化了的数 据或程序代码。

Page 45: 第5章   TMS320C54x 软件开发

2 .条件汇编伪指令 .if 、 .elseif 、 .else 、 .endif 伪指令告诉汇编器按照表达式的计算结果对代码块进行条件汇编。 .if expression — 标志条件块的开始,仅当条件为真

( expression 的值非 0 即为真)时汇编代码。 .elseif expression — 标志若 .if 条件为假,而 .elseif 条件为真时要汇编代码块。 .else — 标志若 .if 条件为假时要汇编代码块。 .endif — 标志条件块的结束,并终止该条件代码块。

Page 46: 第5章   TMS320C54x 软件开发

3 .引用其他文件的伪指令 .copy “ 文件名” — 将指定文件复制到当前位置,其内容可以是程序、数据、符号定义等。 .include “ 文件名” — 与 .copy 类似。只是被

copy 的文件名会出现在汇编时生成的列表中。

如: .copy “d : \dsp\file.asm”

Page 47: 第5章   TMS320C54x 软件开发

.def 符号名 — 在当前文件中定义一个符号,可以被其他文件使用。.ref 符号名 — 在其他文件中定义,可以在本文件中使用的符号。.global 符号名 — 其作用相当于 .def 、 .ref效果之和。 ..def def 符号 符号 [,…,[,…, 符号符号 ]]

..global global 符号 符号 [,…,[,…, 符号符号 ]]..ref ref 符号 符号 [,…,[,…, 符号符号 ]]

如: .def new1,new2

Page 48: 第5章   TMS320C54x 软件开发

.word 数 1 ,数 2 — 指定一个或多个 16 位带符号整数(十六进制)连续放置到存储器中。 .int 数 1 ,数 2 — 指定一个或多个 16 位无符号整数(十六进制)连续放置到存储器中。 .float 数 1 ,数 2 — 指定的各浮点数连续放置到存储器中(从当前段指针开始)。 .space n — 以位为单位,空出 n 位存储空间。 .string “ ” 字符串 [,…,“ ”字符串 ] — 初始化一个或多个字符串。把 8 位字符从一个或多个字符串放进当前段。

4. 初始化常数伪指令

Page 49: 第5章   TMS320C54x 软件开发

【【例例 5-45-4】】比较比较 ..word word ,, ..intint ,, . . floatfloat 和和 ..stringstring 伪指令。伪指令。 源程序:源程序: .word.word 0CCCh0CCCh .int.int 0DDDDh0DDDDh .float.float 1.999991.99999 .string.string “help”“help”

.word:.word: 将一个或多个将一个或多个 1616 位值放入位值放入当前段的连续字中。当前段的连续字中。15 0

0 0 C C C

.int:.int: 将一个或多个将一个或多个 1616 位值放入当位值放入当前段的连续的字中。前段的连续的字中。1 D D D D

.float:.float: 初始化单精度初始化单精度 (32(32 位位 ) ) 浮点数浮点数,并保存在当前段的两个连续的字中,并保存在当前段的两个连续的字中。。

15 0 15 02,3 3 F F F F F A C

.string:.string: 将一个或多个字符串中的将一个或多个字符串中的 88 位位字符放入字符放入当前段中。当前段中。h e

4,5 0 0 6 8 0 0 6 5l P

6,7 0 0 6 C 0 0 7 0

Page 50: 第5章   TMS320C54x 软件开发

列表文件:列表文件:1 1 000000000000 0ccc0ccc .word 0CCCh.word 0CCCh2 2 000001000001 dddddddd .int 0DDDDh.int 0DDDDh3 3 000002000002 3fff3fff .float 1.99999.float 1.99999 000003 000003 ffacffac8 8 000004000004 00680068 .string .string ““helphelp”” 000005000005 00650065 000006000006 006c006c 000007000007 00700070

.float:.float: 自动对准最近长字边界自动对准最近长字边界

Page 51: 第5章   TMS320C54x 软件开发

5.5. 在汇编时定义符号的命令在汇编时定义符号的命令助记符及语法格式 说 明

.asg “字符串” ,替代符号 把一个字符串赋给一个替代符号。替代符号也可以重新被定义。

.label 符号 定义一个特殊的符号,用来指向在当前段内的装载时间地址。

符号 .set 值 用于给符号赋值。符号被存放在符号表中,而且不能被重新定义。

Page 52: 第5章   TMS320C54x 软件开发

66 ..对准段程序计数器的伪指令对准段程序计数器的伪指令..align align 操作数操作数 — — 用于将段程序计数器用于将段程序计数器 ((SPC)SPC) 对准在对准在 11~~128128 字的边界。操作数必须是在字的边界。操作数必须是在 2200~2~21616 之间且等于之间且等于 22 的幂的幂(当然超过(当然超过 2277 是没有意义的)。是没有意义的)。 例如:例如:操作数为操作数为 11 时,对准时,对准 SPCSPC 到字的边界;到字的边界; 操作数为操作数为 22 时,对准时,对准 SPCSPC 到长字到长字 //偶字的边界; 偶字的边界; 操作数为操作数为 128128 时,对准时,对准 SPCSPC 到页面的边界; 到页面的边界; 没有操作数时,没有操作数时, ..alignalign 伪指令默认为伪指令默认为 128128 ,对准页面边界。,对准页面边界。

Page 53: 第5章   TMS320C54x 软件开发

【例【例 5-55-5 】】 ..alignalign 伪指令的使用。 伪指令的使用。 源程序:源程序: .word.word 1234H1234H .align.align 22 .string.string ““Errorcnt”Errorcnt” .align.align .int.int 4000H4000H

; ; 将数值将数值 12341234 放入字指定域放入字指定域中中 ; ; 对准长字边界对准长字边界 ,,SPC=02hSPC=02h ; ; 初始化字符串初始化字符串 ; ; 对准页边界对准页边界 ,,SPC=80hSPC=80h ;; 将数值将数值 40004000 放入指定域中放入指定域中

Page 54: 第5章   TMS320C54x 软件开发

列表文件:列表文件: 11 000000000000 12341234 .WORD 1234H.WORD 1234H 22 .align 2.align 2 33 000002000002 00450045 .string .string ““ErrorcntErrorcnt”” 000003000003 00720072 000004000004 00720072 000005000005 006f006f 000006000006 00720072 000007000007 00630063 000008000008 006e006e 000009000009 00740074 44 .align.align 55 000080000080 00040004 .int 4000H.int 4000H

000000000000

SPC 123412340000000000

11SPC XXXXXX

XX000000000022

SPC 004500450000000000

33SPC 00720072

000000000044

SPC 007200720000000000

55SPC 006F006F

000000000066

SPC 007200720000000000

77SPC 00630063

000000000088

SPC 006E006E0000000000

99SPC 00740074

000080000800

SPC 40004000

Page 55: 第5章   TMS320C54x 软件开发

7 .宏定义和宏调用伪指令伪指令 TMS320C54x 汇编支持宏语言。如果程序中需要多次执行某段程序,可以把这段程序定义(宏定义)为一个宏,然后在需要重复执行这段程序的地方调用这条宏。

返回本节

Page 56: 第5章   TMS320C54x 软件开发

宏定义的格式:宏定义的格式: macnamemacname .macro.macro [parameter[parameter 1][1][ ,,…,…, parameter n]parameter n] …… …….... 宏程序语句宏程序语句或或宏伪指令宏伪指令 [.mexit][.mexit] ..endmendm macname:macname: 宏程序名称,必须将名称放在源程序标号域。宏程序名称,必须将名称放在源程序标号域。

.macro:.macro: 用来说明该语句为宏定义的第一行伪指令,用来说明该语句为宏定义的第一行伪指令, 必须放在助记符操作码区域必须放在助记符操作码区域。。parameters:parameters: 为为任选的替代参数,作为宏指令的操作数。任选的替代参数,作为宏指令的操作数。宏程序语句宏程序语句 :: 每次宏调用时要执行的指令或汇编命令。每次宏调用时要执行的指令或汇编命令。宏伪指令宏伪指令 :: 用于控制宏指令展开的命令。用于控制宏指令展开的命令。..mexit:mexit: 相当于一条相当于一条跳到跳到 ..endmendm 语句。语句。..endm:endm: 结束宏定义。结束宏定义。

Page 57: 第5章   TMS320C54x 软件开发

【【例例 5-65-6】】宏定义、宏调用和宏展开举例宏定义、宏调用和宏展开举例 1 * 1 * 2 * 2 * add3add3 4 *4 * 5 * ADDRP=P1+P2+P35 * ADDRP=P1+P2+P3 6      6       7 add3 .macro P17 add3 .macro P1 ,, P2P2 ,, P3P3 ,, ADDRPADDRP 8       8        9 LD P19 LD P1 ,, AA 10 ADD P210 ADD P2 ,, AA 11 ADD P311 ADD P3 ,, AA 12 STL A12 STL A ,, ADDRPADDRP 13 .endm13 .endm 1414

第第 77~~1414 行行 定义宏:定义宏: add3add3 44 个参数:个参数: P1P1 P2P2 P3P3 ADDRPADDRP

Page 58: 第5章   TMS320C54x 软件开发

15      15       16 .global abc,def,ghi,adr16 .global abc,def,ghi,adr 17 17 18 add3 abc,def,ghi,adr 18 add3 abc,def,ghi,adr 1 1 1 000000 1000! LD abc1 000000 1000! LD abc ,, AA1 000001 0000! ADD def1 000001 0000! ADD def ,, AA1 000002 0000! ADD ghi1 000002 0000! ADD ghi ,, AA1 000003 8000! STL A1 000003 8000! STL A ,, adradr

第第 1818 行行 调用宏:调用宏: add3add3 所用变量:所用变量:abcabc defdef ghighi adradr

共共 44 行行 扩展宏扩展宏 将变量传递给参数将变量传递给参数 abc abc P1P1 def def P2P2 ghi ghi P3P3 adr adr ADDRPADDRP

Page 59: 第5章   TMS320C54x 软件开发

8 .其他伪指令伪指令.mmregs — 定义存储器映射寄存器的名称,这样就可以用 AR0 、 PMST等助记符替换实际的存储器地址。.end — 程序块结束。

Page 60: 第5章   TMS320C54x 软件开发

5.4 链接器命令文件的编写与使用 5.4.1 MEMORY伪指令及其使用 5.4.2 SECTIONS伪指令及其使用

返回首页

Page 61: 第5章   TMS320C54x 软件开发

链接器的主要任务链接器的主要任务是根据链接命令文件是根据链接命令文件 (.(.cmdcmd)),将一个或多个,将一个或多个 COFFCOFF 目标文件链接起来,生成存储目标文件链接起来,生成存储器映像文件器映像文件 (.(.map)map) 和可执行的输出文件和可执行的输出文件 (.(.out)out) 。。 在链接过程中,链接器将各个目标文件合并,并完在链接过程中,链接器将各个目标文件合并,并完成以下工作:成以下工作: ●  ●  将各个段配置到目标系统的存储器。将各个段配置到目标系统的存储器。 ●● 对各个符号和段进行重新定位,并给它们指对各个符号和段进行重新定位,并给它们指 定一个最终的地址。定一个最终的地址。 ●● 解决输入文件之间未定义的外部引用。 解决输入文件之间未定义的外部引用。

Page 62: 第5章   TMS320C54x 软件开发

【例【例 5-75-7 】】 链接器命令文件举例。 链接器命令文件举例。 aa..obj bobj b..obj obj /* /* 输入文件名 输入文件名 */*/ -o prog-o prog..out out /*/* 指定输出文件的选项指定输出文件的选项 */*/ --m progm prog..map map /*/* 指定指定 mapmap 文件的选项文件的选项 */*/ MEMORY MEMORY /*MEMORY /*MEMORY 伪指令伪指令 */*/ {{ PAGE 0PAGE 0 : : ROMROM :: origin=1000h, origin=1000h, length=0100hlength=0100h PAGE 1PAGE 1 : : RAMRAM :: origin=0100h, origin=0100h, length=0100h length=0100h } } SECTIONS SECTIONS /*SECTIONS/*SECTIONS 伪指令伪指令 */*/ {{ ..text text : : >ROM >ROM ..data data :: >ROM >ROM ..bss bss : : >RAM >RAM } }

Page 63: 第5章   TMS320C54x 软件开发

注意:在命令文件中,不能采用下列符号作为段名或符号名:注意:在命令文件中,不能采用下列符号作为段名或符号名: align DSECT len o runalign DSECT len o run ALIGN f length org RUNALIGN f length org RUN attr fill LENGTH origin SECTIONSattr fill LENGTH origin SECTIONS ATTR FILL load ORIGIN spareATTR FILL load ORIGIN spare block group LOAD page type block group LOAD page type BLOCK GROUP MEMORY PAGE BLOCK GROUP MEMORY PAGE TYPE TYPE COPY l(COPY l( 小写小写 L) NOLOAD range L) NOLOAD range UNIONUNION

Page 64: 第5章   TMS320C54x 软件开发

5.4.1 MEMORY 伪指令及其使用

返回本节

MEMORYMEMORY 指令用来规定目标存储器的结构。指令用来规定目标存储器的结构。 在实际的应用中,目标系统所配置的存储器是各在实际的应用中,目标系统所配置的存储器是各不相同的,通过不相同的,通过 MEMORYMEMORY 指令,可以进行各种各指令,可以进行各种各样的存储器配置。 样的存储器配置。

MEMORYMEMORY 指令的句法:指令的句法: MEMORYMEMORY{{ PAGE0PAGE0 :: name 1[(attr)]name 1[(attr)] :: origin=constantorigin=constant, , length=constantlength=constant ;;

PAGEnPAGEn :: name n[(attr)]name n[(attr)] :: origin=constantorigin=constant,, length=constantlength=constant ;;

} }

指令字指令字

存储区间说明语句存储区间说明语句书写方式书写方式::① ① 已大写已大写 MEMORYMEMORY 指令字开始;指令字开始; ② ② 由大括号括起来的存储器区间说明。由大括号括起来的存储器区间说明。存储区间:存储区间:存储页面存储页面 区间名称区间名称 区间属性区间属性 起始地址起始地址 区间长度区间长度

Page 65: 第5章   TMS320C54x 软件开发

存储区间说明语句:存储区间说明语句: PAGE:PAGE: 指定存储器空间页面,最多为指定存储器空间页面,最多为 255255页,页, 取决于目标存储器的配置。取决于目标存储器的配置。 每一个每一个 PAGEPAGE 代表一个完全独立的地址空间。代表一个完全独立的地址空间。 通常,通常, PAGE 0PAGE 0 用于程序存储器;用于程序存储器; PAGE 1PAGE 1 用于数据存储器。用于数据存储器。 若没有规定若没有规定 PAGEPAGE ,,则链接器默认为则链接器默认为 PAGE 0PAGE 0 。 。

Page 66: 第5章   TMS320C54x 软件开发

存储区间说明语句:存储区间说明语句: name:name: 存储器区间名称。可由用字母、存储器区间名称。可由用字母、$$ 、、 .. 、、 __ 等组成等组成。。 存储器区间为内部记号,因此不需要保留在输出文存储器区间为内部记号,因此不需要保留在输出文件或者符号表中。件或者符号表中。 不同不同 PAGEPAGE 上的存储器区间可以取相同的名字,上的存储器区间可以取相同的名字,但在同一但在同一 PAGEPAGE 内的名字不能相同内的名字不能相同 ,, 且不许重叠配置且不许重叠配置。。

Page 67: 第5章   TMS320C54x 软件开发

存储区间说明语句:存储区间说明语句: attr:attr: 为任选项,用来为命名的存储器区间规为任选项,用来为命名的存储器区间规 定定 11~~44 个属性。个属性。 当对输出段定位时当对输出段定位时 ,, 可利用属性限制输出段分配可利用属性限制输出段分配到一定的存储区间。到一定的存储区间。 属性选项共有属性选项共有 44项:项: RR 规定可以对存储器执行读操作。规定可以对存储器执行读操作。 W W 规定可以对存储器执行写操作。规定可以对存储器执行写操作。 XX 规定存储器可以装入可执行的程序代码。规定存储器可以装入可执行的程序代码。 I I 规定可以对存储器进行初始化。规定可以对存储器进行初始化。

若未选属性,可将输出段不受限制地定位到任何一若未选属性,可将输出段不受限制地定位到任何一个存储器的位置。个存储器的位置。 任何一个没有规定属性的存储器任何一个没有规定属性的存储器 ((包括所有默认方包括所有默认方式的存储器式的存储器 ))都有全部都有全部 44项属性。项属性。

Page 68: 第5章   TMS320C54x 软件开发

存储区间说明语句:存储区间说明语句: origin: origin: 用来指用来指定存储区间的起始地址,可简定存储区间的起始地址,可简 写为写为 orgorg 或或 oo 。其值以字为单位,可以。其值以字为单位,可以 用十进制、八进制或十六进制数表示。用十进制、八进制或十六进制数表示。 Length:Length: 用来用来指定存储器空间的长度,可简写指定存储器空间的长度,可简写 为为 lenlen 或或 ll ,,其值以字为单位,可以用其值以字为单位,可以用 十进制、八进制或十六进制数表示。十进制、八进制或十六进制数表示。

Page 69: 第5章   TMS320C54x 软件开发

存储区间说明语句:存储区间说明语句: fill:fill: 为任选项。用来为没有定位输出段的存储为任选项。用来为没有定位输出段的存储 器空单元充填一个数,键入器空单元充填一个数,键入 fillfill 或或 ff 均可。均可。 该值是该值是 22 个字节的整型常数,可以是十进制个字节的整型常数,可以是十进制 数、八进制数或十六制数数、八进制数或十六制数 。 。

Page 70: 第5章   TMS320C54x 软件开发

【【例例 5--85--8 】】用用 MEMORYMEMORY 伪指令编写连接命令文件。要求伪指令编写连接命令文件。要求:: 程序存储器:程序存储器: 44KK 字字 ROMROM ,,起始地址为起始地址为 C00hC00h ,,取名为取名为ROMROM 。。 数据存储器:数据存储器: 3232 字字 RAMRAM ,,起始地址为起始地址为 6060hh ,,取名为取名为SCRSCR 。。 512512 字字 RAMRAM ,,起始地址为起始地址为 8080hh ,,取名为取名为CHIPCHIP 。。

file1.obj fiel2.obj file1.obj fiel2.obj -o Prog.out -o Prog.out MEMORYMEMORY{{ PAGE 0PAGE 0 :: ROMROM : : origin=C00h, origin=C00h, length=1000hlength=1000h PAGE 1PAGE 1 :: SCRSCR :: origin=60h, origin=60h, length=20hlength=20h CHIPCHIP :: origin=80h, length=200horigin=80h, length=200h}}

两个输入文件链接命令选项

指令字

页面名称 区间名称 起始地址 区间长度

Page 71: 第5章   TMS320C54x 软件开发

【【例例 5-85-8 】】用用 MEMORYMEMORY 伪指令编写连接命令文件。伪指令编写连接命令文件。file1.obj fiel2.obj file1.obj fiel2.obj -o Prog.out -o Prog.out MEMORYMEMORY{{PAGE 0PAGE 0 :: ROMROM : : org=C00h, len=1000horg=C00h, len=1000hPAGE 1PAGE 1 :: SCRSCR :: org=60h, len=20horg=60h, len=20h CHIPCHIP :: org=80h, len=200horg=80h, len=200h}}

PAGE 0PAGE 0 : : ROMROM : : org=C00h, org=C00h, len=1000hlen=1000h

程序存储器

00000h

0FFFFh

0000C00hC00h1001000h0h 0101C00hC00h

ROMROM

PAGE 1PAGE 1 :: SCRSCR :: org=60h, org=60h, len=20hlen=20h

数据存储器

00000h

0FFFFh

0000060h060h000007Fh07Fh20h20h SCRSCR

CHIPCHIP :: org=80h, org=80h, len=200hlen=200h

0000080h080h200200hh 00270027FhFh

CHIPCHIP

Page 72: 第5章   TMS320C54x 软件开发

5.4.2 SECTIONS 伪指令及其使用 SECTIONS 伪指令用来控制段的构成与地址分配。用来控制段的构成与地址分配。 指令功能:指令功能: ①① 说明如何将输入段组合成输出段;说明如何将输入段组合成输出段; ②② 在可执行程序中定义输出段;在可执行程序中定义输出段; ③ ③ 规定输出段在存储器中的存放位置;规定输出段在存储器中的存放位置; ④ ④ 允许重新命名输出段。允许重新命名输出段。

Page 73: 第5章   TMS320C54x 软件开发

SECTIONSSECTIONS 指令的句法:指令的句法: SECTIONSSECTIONS{{ namename :: [property[property, , propertyproperty, , propertyproperty, , …]…] namename :: [property[property, , propertyproperty, , propertyproperty, , …]…] namename :: [property[property, , propertyproperty, , propertyproperty, , …]…]} }

指令字指令字输出段输出段说明语句说明语句

段名:段名:定义输出段的名称。定义输出段的名称。 属性属性::定义该段的内容和存储器的分配。定义该段的内容和存储器的分配。

段名段名

1.1. SECTIONSSECTIONS 指令语法指令语法

属性属性 属性属性 属性属性

Page 74: 第5章   TMS320C54x 软件开发

1.1. SECTIONSSECTIONS 指令语法指令语法 段属性用来定义输出段的内容和存储地址的分配段属性用来定义输出段的内容和存储地址的分配。包括的内容如下:。包括的内容如下: ① ① 装入存储器分配装入存储器分配 ②② 运行存储器分配运行存储器分配 ③ ③ 输入段输入段 ④ ④ 段的类型段的类型 ⑤ ⑤ 充填值充填值

Page 75: 第5章   TMS320C54x 软件开发

1.1. SECTIONSSECTIONS 指令语法指令语法①① 装入存储器分配装入存储器分配 用于定义段装入时的存储器地址。用于定义段装入时的存储器地址。语法格式: 语法格式: load=allocationload=allocation 或 或 allocationallocation 或或 > > allocationallocation allocation: allocation: 关于段地址的说明,即给段分配存储关于段地址的说明,即给段分配存储 单元。单元。

Page 76: 第5章   TMS320C54x 软件开发

1.1. SECTIONSSECTIONS 指令语法指令语法①① 装入存储器分配装入存储器分配例如:例如: .text: load=0x1000.text: load=0x1000

..text: load>ROMtext: load>ROM

..bss: load>bss: load> (( RWRW ))

..texttext:: align=0x80 align=0x80

..text: PAGE 0 text: PAGE 0

..bss: load=block(0x80)bss: load=block(0x80)

将将 ..texttext 段定位到一个特定的地址。段定位到一个特定的地址。 将将 ..texttext 段定位到命名为段定位到命名为 ROMROM 的存储区的存储区。 。 将将 ..bssbss 段定位到属性为段定位到属性为 RR 、、 WW 的存储的存储区。区。 将将 ..texttext 段定位到从地址段定位到从地址 00x80x80 开始。开始。 将将 ..texttext 段定位到段定位到 PAGE 0PAGE 0 。。

将将 ..bssbss 段定位到一个段定位到一个 nn 字存储器块字存储器块 的任何一个位置的任何一个位置 ((nn 为为 22 的幂次的幂次 )) 。。

Page 77: 第5章   TMS320C54x 软件开发

1.1. SECTIONSSECTIONS 指令语法指令语法①① 装入存储器分配装入存储器分配 若用到一个以上参数,可以将它们排成一行。若用到一个以上参数,可以将它们排成一行。 例如:例如: ..texttext: : >ROM >ROM ((alignalign (( 1616 )) PAGE PAGE ((2 2 )))) 。。

Page 78: 第5章   TMS320C54x 软件开发

1.1. SECTIONSSECTIONS 指令语法指令语法 链接器为段在目标存储器中分配两个地址:链接器为段在目标存储器中分配两个地址: 加载的地址加载的地址——由装入存储器分配完成——由装入存储器分配完成 执行程序的地址执行程序的地址——由运行存储器分配完成——由运行存储器分配完成 通常,这两个地址是相同的。通常,这两个地址是相同的。 若要想把程序的加载区分开,先将程序加载到若要想把程序的加载区分开,先将程序加载到ROMROM ,,然后在然后在 RAMRAM 中运行,则用中运行,则用 SECTIONSSECTIONS命令让链接器对这个段定位两次即可。命令让链接器对这个段定位两次即可。 例如:例如: ..firfir : : load=ROMload=ROM ,, run=RAMrun=RAM

Page 79: 第5章   TMS320C54x 软件开发

1.1. SECTIONSSECTIONS 指令语法指令语法③③ 输入段输入段 用于定义组成输出段的输入段。用于定义组成输出段的输入段。语法格式: 语法格式: {input_sections}{input_sections} 大多数情况下,在大多数情况下,在 SECTIONSSECTIONS 命令中是不列出每命令中是不列出每个输入文件的输入段的段名。个输入文件的输入段的段名。 例如: 例如: SECTIONSSECTIONS {{ ..texttext:: ..datadata:: ..bssbss }}

链接时:在输入文件中的链接时:在输入文件中的所有所有 ..texttext 段链接成段链接成 ..texttext 输出段输出段所有所有 ..datadata 段链接成段链接成 ..datadata 输出段输出段所有所有 ..bssbss 段链接成段链接成 ..bssbss 输出段输出段

Page 80: 第5章   TMS320C54x 软件开发

1.1. SECTIONSSECTIONS 指令语法指令语法 用用文件名和段名来规定输入段。文件名和段名来规定输入段。 SECTIONSSECTIONS {{ .text: .text: /*/* 创建 创建 ..text text 输出段输出段 */*/ {{ f1.obj(.text) f1.obj(.text) /*/* 链接来自链接来自 f1.objf1.obj 文件中的文件中的 ..text text 段段 */*/ f2.obj(sec1) f2.obj(sec1) /*/* 链接来自链接来自 f2.objf2.obj 文件中的文件中的 sec1 sec1 段段 */*/

f3.obj f3.obj /*/* 链接来自链接来自 f3.objf3.obj 文件中的所有段文件中的所有段 */*/

f4.obj(.text,sec2) f4.obj(.text,sec2) /*/* 链接链接 f4.objf4.obj 文件中的文件中的 ..text text 段和段和 sec2sec2段段 */*/ }} } }

Page 81: 第5章   TMS320C54x 软件开发

1.1. SECTIONSSECTIONS 指令语法指令语法④④ 段的类型段的类型 用于为输出段定义特殊形式的标记 。用于为输出段定义特殊形式的标记 。语法格式: 语法格式: type=COPYtype=COPY 或 或 type=DSECTtype=DSECT 或或 type=NOLOADtype=NOLOAD ⑤ ⑤ 充填值充填值 用于对未初始化空单元定义一个数值。用于对未初始化空单元定义一个数值。语法格式: 语法格式: fill=valuefill=value 或或 namename …:…: {{……}=value}=value

Page 82: 第5章   TMS320C54x 软件开发

2.2. SECTIONSSECTIONS 指令的使用指令的使用 【【例例 5-95-9】】 SECTIONSSECTIONS 指令的使用指令的使用。。 file1.obj file2.obj file1.obj file2.obj -o Prog.out-o Prog.out SECTIONSSECTIONS {{ .text: .text: load=ROMload=ROM ,, run=800hrun=800h .con: load=ROM.con: load=ROM .bss: load=RAM.bss: load=RAM .vec: load=FF80h.vec: load=FF80h {{ t1.obj(.int1)t1.obj(.int1) t2.obj(.int2)t2.obj(.int2) endvec=.endvec=.;; }} .data: align=16.data: align=16 }}

两个输入文件链接命令选项指令字输出段说明语句

Page 83: 第5章   TMS320C54x 软件开发

2.2. SECTIONSSECTIONS 指令的使用指令的使用 【【例例 5-95-9】】 SECTIONSSECTIONS 指令的使用指令的使用。。 file1.obj file2.obj file1.obj file2.obj -o Prog.out-o Prog.out SECTIONSSECTIONS {{ .text: .text: load=ROMload=ROM ,, run=800hrun=800h .con: load=ROM.con: load=ROM .bss: load=RAM.bss: load=RAM .vec: load=FF80h.vec: load=FF80h {{ t1.obj(.int1)t1.obj(.int1) t2.obj(.int2)t2.obj(.int2) endvec=.endvec=.;; }} .data: align=16.data: align=16 }}

输出段 加载地址 运行地址.text ROM RAM

800h.con ROM.bss RAM.vec ROM FF80

.data RAM 16 位边界

Page 84: 第5章   TMS320C54x 软件开发

2.2. SECTIONSSECTIONS 指令的使用指令的使用 【【例例 5-9 5-9 】】 SECTIONSSECTIONS 指令的使指令的使用。用。 file1.obj file2.obj file1.obj file2.obj -o Prog.out-o Prog.out SECTIONSSECTIONS {{ .text: .text: load=ROMload=ROM ,, run=800hrun=800h .con: load=ROM.con: load=ROM .bss: load=RAM.bss: load=RAM .vec: load=FF80h.vec: load=FF80h {{ t1.obj(.int1)t1.obj(.int1) t2.obj(.int2)t2.obj(.int2) endvec=.endvec=.;; }} .data: align=16.data: align=16 }}

输出段 加载地址 运行地址.text ROM RAM

800h.con ROM.bss RAM.vec ROM FF80.data RAM 16 字边界

ROM RAM00h

.text

.con

.bss

.vec

.dataFF80FF80

hh

运行时运行时

800h800h

.text

.text

.text

Page 85: 第5章   TMS320C54x 软件开发

5.5 汇编语言程序编写方法 5.5.1 汇编语言源程序格式 5.5.2 汇编语言中的常数和字符串 5.5.3 汇编源程序中的符号 5.5.4 汇编源程序中的表达式

返回首页

Page 86: 第5章   TMS320C54x 软件开发

5.5.1 汇编语言源程序格式 汇编语言程序以汇编语言程序以 ..asmasm 为扩展名,可以用任意的编为扩展名,可以用任意的编辑器编写源文件。一条语句占源程序的一行,长度可辑器编写源文件。一条语句占源程序的一行,长度可以是源文件编辑器格式允许的长度,但汇编器每行最以是源文件编辑器格式允许的长度,但汇编器每行最多读多读 200200 个字符。因此,语句的执行部分必须限制在个字符。因此,语句的执行部分必须限制在200200 个字符以内。个字符以内。

Page 87: 第5章   TMS320C54x 软件开发

1.1. 源文件格式 源文件格式 助记符指令源语句的每一行通常包含助记符指令源语句的每一行通常包含 44 个部分:标个部分:标号区、助记符区、操作数区和注释区。号区、助记符区、操作数区和注释区。 [[标号标号 ][:]][:] 助记符助记符 [[ 操作数操作数 ] ] [[; ; 注释注释 ]]助记符指令语法格式:助记符指令语法格式: 【例【例 5-105-10 】】 助记符指令源语句举例。助记符指令源语句举例。 NANHUA NANHUA .set.set 11 ; ; 符号符号 NANHUANANHUA == 11 Begin:Begin: LDLD #NANHUA#NANHUA ,, AR1AR1 ; ; 将将 11 加载到加载到AR1AR1 标 号 标 号 助记符 助记符 操作数 操作数 注 释 注 释

Page 88: 第5章   TMS320C54x 软件开发

1.1. 源文件格式 源文件格式 语句的书写规则:语句的书写规则: ① ① 所有语句必须以标号、空格、星号或分号所有语句必须以标号、空格、星号或分号(*(*或;或; ))开始;开始;② ② 标号是可选项,若使用标号,则标号必须标号是可选项,若使用标号,则标号必须从第一列开始;从第一列开始; ③ ③ 所有包含有汇编伪指令的语句必须在一行所有包含有汇编伪指令的语句必须在一行完成指定;完成指定;④ ④ 各部分之间必须用空格分开,各部分之间必须用空格分开, TabTab 字符与字符与空格等效;空格等效;

Page 89: 第5章   TMS320C54x 软件开发

1.1. 源文件格式 源文件格式 语句的书写规则:语句的书写规则: ⑤ ⑤ 程序中注释是可选项。如果注释在第一列开程序中注释是可选项。如果注释在第一列开

始时始时,,前面必须标上星号或分号,在其他列前面必须标上星号或分号,在其他列开始的注释前面必须以分号开头;开始的注释前面必须以分号开头;

⑥ ⑥ 如果源程序很长,需要书写若干行,可以在如果源程序很长,需要书写若干行,可以在前一行用反斜杠字符(前一行用反斜杠字符( \\ )结束,余下部分)结束,余下部分接着在下一行继续书写。接着在下一行继续书写。

Page 90: 第5章   TMS320C54x 软件开发

2.2. 标号标号 所有汇编指令和大多数汇编伪指令都可以选用标号,所有汇编指令和大多数汇编伪指令都可以选用标号,供本程序或其它程序调用。供本程序或其它程序调用。① ① 标号必须从语句的第标号必须从语句的第 11 列写起,其后的冒列写起,其后的冒号“号“ :”:” 可任选; 可任选; ② ② 标号为任选项,若不使用标号,则语句的标号为任选项,若不使用标号,则语句的第一列必须是空格、星号或分号; 第一列必须是空格、星号或分号; ③ ③ 标号是由字母、数字以及下划线和美元符标号是由字母、数字以及下划线和美元符号等组成,最多可达号等组成,最多可达 3232 个字符;个字符;④④ 标号分大小写,且第一个字符不能是数字。标号分大小写,且第一个字符不能是数字。

Page 91: 第5章   TMS320C54x 软件开发

2.2. 标号 标号 在使用标号时,标号的值是段程序计数器在使用标号时,标号的值是段程序计数器 SPCSPC 的的当前值。当前值。 例如,若使用例如,若使用 ..wordword 伪指令初始化几个字,则标号伪指令初始化几个字,则标号将指到第一个字。将指到第一个字。 【例【例 5-115-11】】 标号格式举例。标号格式举例。 …… …… 99 000000000000 1010 000040000040 000000AA StartStart :: ..word 0Ahword 0Ah ,, 33 ,, 77 000041000041 00030003 000042000042 00070007

;;假设汇编了某个其他代码假设汇编了某个其他代码

标号,值为标号,值为 4040hh

Page 92: 第5章   TMS320C54x 软件开发

3.3. 助记符助记符 助记符助记符用来表示指令所完成的操作,用来表示指令所完成的操作,可以是汇编可以是汇编语言指令、汇编伪指令、宏伪指令。语言指令、汇编伪指令、宏伪指令。助记符指令:助记符指令:一般用大写,一般用大写,不能从第一列开始不能从第一列开始 ; ; 汇编伪指令:汇编伪指令:用来为程序提供数据和控制汇编进程。用来为程序提供数据和控制汇编进程。以句号“以句号“ .”.” 开始,且用小写;开始,且用小写;宏伪指令:宏伪指令:用来定义一段程序,以便宏调用来调用这用来定义一段程序,以便宏调用来调用这段程序。以句号“段程序。以句号“ ..”” 开始,且用小写;开始,且用小写; 宏调用:宏调用:用来调用由宏伪指令定义的程序段。用来调用由宏伪指令定义的程序段。

Page 93: 第5章   TMS320C54x 软件开发

4.4. 操作数操作数 操作数是指操作数是指指令中参与操作的数值或汇编伪指令指令中参与操作的数值或汇编伪指令定义的内容,紧跟在助记符的后面,由一个或多个空定义的内容,紧跟在助记符的后面,由一个或多个空格分开。格分开。 操作数之间必须用逗号“,”分隔;操作数之间必须用逗号“,”分隔; 操作数可以是常数、符号或表达式; 操作数可以是常数、符号或表达式; 操作数中的常数、符号或表达式可用来作为地址、操作数中的常数、符号或表达式可用来作为地址、

立即数或间接地址;立即数或间接地址;

Page 94: 第5章   TMS320C54x 软件开发

4.4. 操作数操作数指令的操作数前缀指令的操作数前缀 ::

使用“使用“ #”#” 符号作为操作数的前缀;符号作为操作数的前缀; 使用使用““ **””符号作为符号作为操作数的操作数的前缀前缀; ; 使用使用““ @@”” 符号作为符号作为操作数的操作数的前缀前缀。。

汇编器允许指定的常数、符号或表达式作为地址、汇编器允许指定的常数、符号或表达式作为地址、立即数或间接地址。立即数或间接地址。 作为操作数的前缀有三种情况:作为操作数的前缀有三种情况:

Page 95: 第5章   TMS320C54x 软件开发

① ① 用“用“ ##”” 作作前缀前缀

例如:例如: LabelLabel: : ADDADD ## 99,99, B B

使用“使用“ ##”” 号作为前缀,汇编器将操作数作为立号作为前缀,汇编器将操作数作为立即数处理。即使操作数是寄存器或地址,也将作为即数处理。即使操作数是寄存器或地址,也将作为立即数。立即数。 如果操作数是地址,汇编器将把地址处理为一个如果操作数是地址,汇编器将把地址处理为一个数值,而不使用地址的内容。数值,而不使用地址的内容。

操作数操作数 ## 99 99 是一个立即数。是一个立即数。

Page 96: 第5章   TMS320C54x 软件开发

② ② 用“用“ *”*”作作前缀前缀

例如:例如: LabelLabel: : LDLD * * AR3 AR3, , BB

使用“使用“ *”*” 符号作为前缀,汇编器将操作数作为间符号作为前缀,汇编器将操作数作为间接地址,即把操作数的内容作为地址。接地址,即把操作数的内容作为地址。

操作数操作数 **AR3AR3 指定一个间接地址。该指令将引导指定一个间接地址。该指令将引导汇编器找到寄存器汇编器找到寄存器 AR3AR3 的内容作为地址,然后将该的内容作为地址,然后将该地址中的内容装入指定的累加器地址中的内容装入指定的累加器 BB 中。 中。

Page 97: 第5章   TMS320C54x 软件开发

③ ③ 用“用“ @@””作作前缀前缀

例如:例如: LabelLabel: : LDLD @ x@ x, , AA

使用“使用“ @@”” 符号作为前缀,汇编器将操作数作为符号作为前缀,汇编器将操作数作为直接地址,即操作数由直接地址码赋值。直接地址,即操作数由直接地址码赋值。

只要只要 DP=0DP=0 ,,将直接地址将直接地址 xx 中的内容装入指定的累中的内容装入指定的累加器加器 AA 中。中。

Page 98: 第5章   TMS320C54x 软件开发

5.5. 注释注释 用来说明指令功能的文字,便于用户阅读。用来说明指令功能的文字,便于用户阅读。 注释可注释可位于句首位于句首或或句尾句尾,,位于句首时,位于句首时,以以““ **””或或

““;;”开始”开始,位于句尾时,,位于句尾时, “ ”以分号 ; 开始。“ ”以分号 ; 开始。 注释可注释可单独一行或数行单独一行或数行;; 注释是任选项。注释是任选项。 11 00000 .11 00000 .bss symbss sym, , ; ; 保留空间于保留空间于 ..bssbss

**************************************************************************** * * 改变段,允许第五个‘改变段,允许第五个‘ mylabmylab’’定义 定义 ** ****************************************************************************

例如:例如:

Page 99: 第5章   TMS320C54x 软件开发

5.5.2 汇编语言中的常数和字符串表 5-3 COFF 常数与字符串

返回本节 汇编器可支持汇编器可支持 77种类型的常数(常量)。种类型的常数(常量)。

Page 100: 第5章   TMS320C54x 软件开发

字符常数是包括在单引号内的字符串。若单引号之字符常数是包括在单引号内的字符串。若单引号之间没有字符,则值为间没有字符,则值为 00 。每个字符在内部表示为。每个字符在内部表示为 88 位位ASCIIASCII 码。码。 例如例如:: ‘‘aa’ ’ 内部表示为内部表示为 6161 hh ‘‘BB’’ 内部表示为内部表示为 4242 hh “‘“‘D’ D’ 内部表示为内部表示为 2744h2744h

注意注意::字符常数与字符串的差别字符常数与字符串的差别。。 字字符常数代表单个整数值符常数代表单个整数值。 。 字符串只是一串字符字符串只是一串字符。。

Page 101: 第5章   TMS320C54x 软件开发

5.5.3 汇编源程序中的符号 汇编程序中的符号用于标号、常数和替代字符。 汇编程序中的符号用于标号、常数和替代字符。 由字母、数字以及下划线和美元符号由字母、数字以及下划线和美元符号

(( AA~~ZZ ,, aa~~zz ,, 00~~99 ,, __ 和和 $$ )等组成;)等组成; 符号名最多可长达符号名最多可长达 200200 个字符;个字符; 在符号中,第在符号中,第 11 位不能是数字,并且符号中不位不能是数字,并且符号中不

能含空格。能含空格。

Page 102: 第5章   TMS320C54x 软件开发

1.1. 标号标号 作为标号的符号代表在程序中对应位置的符号地址作为标号的符号代表在程序中对应位置的符号地址。。 通常,标号是局部变量,在一个文件中局部使用的通常,标号是局部变量,在一个文件中局部使用的标号必须是唯一的。标号必须是唯一的。 标号分大小写。标号分大小写。 例如:例如: ABCABC ,, AbcAbc ,, abcabc 是是 33 个不同的符号。个不同的符号。 在调用汇编器时使用在调用汇编器时使用 --cc 选项,可以不分大小写。选项,可以不分大小写。

Page 103: 第5章   TMS320C54x 软件开发

1.1. 标号标号 标号还可以作为标号还可以作为 ..globalglobal ,, ..refref ,, ..defdef 或或 ..bssbss等汇编伪指令的操作数。等汇编伪指令的操作数。 如:如: ..globalglobal labellabel lable1lable1 NOPNOP ADDADD labellabel ,, BB BB label1label1

Page 104: 第5章   TMS320C54x 软件开发

2.2. 局部标号 局部标号 局部标号是一种特殊的标号,使用的范围和影响是局部标号是一种特殊的标号,使用的范围和影响是临时性的。临时性的。 定义方法:定义方法:

注意:注意:局部标号不能用伪指令来定义局部标号不能用伪指令来定义。 。

① ① 用用 $$nn 来定义。来定义。 nn 是是 0~90~9 的十进制数;的十进制数; ② ② 用用 NAME?NAME? 定义。定义。 NAMENAME 是任何一个合法的符是任何一个合法的符号名。汇编器用紧随其后一个唯一的数值代替号名。汇编器用紧随其后一个唯一的数值代替问号。宏中定义标号不声明为全局标号。 问号。宏中定义标号不声明为全局标号。

Page 105: 第5章   TMS320C54x 软件开发

局部标号可以被取消定义,并可以再次被定义或自局部标号可以被取消定义,并可以再次被定义或自动产生。动产生。 取消局部变量的方法:取消局部变量的方法: ① ① 使用使用 ..newblocknewblock 伪指令; 伪指令; ② ② 使用伪指令使用伪指令 ..sectsect ,, .text.text 或或 ..datadata改变段改变段 ;; ③ ③ 使用伪指令使用伪指令 ..includeinclude 或或 ..copycopy ,,进入进入 includeinclude 文件文件;; ④ ④ 达到达到 includeinclude 文件的结尾,离开文件的结尾,离开 includeinclude 文件。 文件。

Page 106: 第5章   TMS320C54x 软件开发

【【例例 5-125-12 】】合法、非法局部标号合法、非法局部标号 $$nn 举例。举例。 假设符号假设符号 ADDRAADDRA ,, ADDRBADDRB ,, ADDRCADDRC 已经在前面作已经在前面作了定义。了定义。 Label1Label1 : : LD ADDRA,ALD ADDRA,A SUB ADDRB,A SUB ADDRB,A BC $1,ALTBC $1,ALT LD ADDRB,ALD ADDRB,A B $2B $2 $1 $1 LD ADDRA,ALD ADDRA,A $2 ADD ADDRC,A$2 ADD ADDRC,A .newblock.newblock BC $1,ALTBC $1,ALT STL A,ADDRCSTL A,ADDRC $1 NOP$1 NOP

;;将将 ADDRAADDRA 装入累加器装入累加器 A A ;;减去地址减去地址 B B ;;如果小于如果小于 00,分支转移到,分支转移到 $1 $1 ;;否则将否则将 ADDRBADDRB 装入累加器装入累加器 A A ;;分支转移到分支转移到 $2 $2 ;; $1$1 ::将将 ADDRAADDRA 装入累加器装入累加器 A A ;; $2$2 ::加上加上 ADDRC ADDRC ;;取消取消 $1$1 的定义,使它可被再次使的定义,使它可被再次使用用 ;;若小于若小于 00 ,分支转移到,分支转移到 $1 $1 ;;存存 ACCACC 的低的低 1616 位到位到 ADDRC ADDRC

.newblock.newblock .newblock.newblock BC $1,ALT BC $1,ALT ;;若小于若小于 00 ,分支转移到,分支转移到 $1 $1 STL A,ADDRC STL A,ADDRC ;;存存 ACCACC 的低的低 1616 位到位到ADDRC ADDRC $1 NOP$1 NOP

;;错误:错误: $1$1 被多次定义 被多次定义

Page 107: 第5章   TMS320C54x 软件开发

【【例例 55-13-13 】】 name?name? 形式的局部标号的使用方法。 形式的局部标号的使用方法。 ;; **************************************************************************************** ; ; 局部标号局部标号‘‘ mylabmylab’’ 的第的第 11 个定义 个定义 ;; **************************************************************************************** NOPNOP mylab? NOPmylab? NOP B mylab?B mylab? ;; ************************************************************************************** .copy“a.inc” .copy“a.inc” ;; ************************************************************************************** mylab? NOPmylab? NOP B mylab?B mylab?

;;包括文件中有‘包括文件中有‘mylab’mylab’ 第第 22次定义次定义 ;从包括文件中退出复位后,;从包括文件中退出复位后, ‘ ‘mylab’mylab’ 的第的第 33 个定义 个定义

Page 108: 第5章   TMS320C54x 软件开发

;; **************************************************************************************** ; ; ‘在宏中‘在宏中 mylab’mylab’的第的第 44个定义,个定义, ; ; 为了避免冲突,宏使用不同的名称空间为了避免冲突,宏使用不同的名称空间 ;; **************************************************************************************** maymac .macro maymac .macro mylab? NOP mylab? NOP B mylab?B mylab? .endm .endm ;; ************************************************************************************** mymacmymac B mylab? B mylab?

;宏调用。引用‘;宏调用。引用‘mylab'mylab' 的第的第 33 个定义 个定义 ;既不被宏调用复位,也不与定义在;既不被宏调用复位,也不与定义在 宏中的相同名冲突 宏中的相同名冲突

Page 109: 第5章   TMS320C54x 软件开发

;; **************************************************************************************** ; ; ‘改变段,允许‘改变段,允许 mylab'mylab'的第的第 55 个定义 个定义 ;; **************************************************************************************** .sect.sect “Secto_One” “Secto_One” NOP NOP mylabmylab ? ? .word 0 .word 0 NOPNOP NOPNOP B mylab? B mylab?

Page 110: 第5章   TMS320C54x 软件开发

3.3. 符号常数 符号常数 符号也可被设置成常数值。为了提高程序的可读性符号也可被设置成常数值。为了提高程序的可读性,可以用有意义的名称来代表一些重要的常数值。,可以用有意义的名称来代表一些重要的常数值。 伪指令伪指令 ..setset 和和 ..sstructtruct // ..tagtag // ..endstructendstruct 可可以用来将常数赋给符号名。以用来将常数赋给符号名。 注意:注意:符号常数不能被重新定义。符号常数不能被重新定义。

Page 111: 第5章   TMS320C54x 软件开发

【例【例 55-14-14 】】 定义符号常数举例。定义符号常数举例。 N .set 512 N .set 512 buffer .set 4 * Nbuffer .set 4 * N nzg1 .set 1nzg1 .set 1 nzg2 .set 2nzg2 .set 2 nzg3 .set 3nzg3 .set 3

AUX .set AR1AUX .set AR1 MVMM AUX , SPMVMM AUX , SP

;;定义符号常数定义符号常数

;将符号常数赋给寄;将符号常数赋给寄;存器,符号名作为;存器,符号名作为;寄存器的别名;寄存器的别名

Page 112: 第5章   TMS320C54x 软件开发

4.4. 预先定义的符号常数 预先定义的符号常数 汇编器有若干预先定义符号,包括:汇编器有若干预先定义符号,包括: ① ① 美元符号美元符号 $$ ,代表段程序指针,代表段程序指针 SPCSPC的当前值的当前值

;; ② ② 映像映像寄存器符号寄存器符号,,包括包括 AR0~AR7AR0~AR7 ;;

③③ 映像寄存器由汇编器设置为符号。映像寄存器由汇编器设置为符号。

Page 113: 第5章   TMS320C54x 软件开发

5.5. 替代符号 替代符号 可将字符串值可将字符串值 (( 变量变量 ))赋给符号,使符号名与该变赋给符号,使符号名与该变量等效,成为字符串的别名,这种用来代表变量的符量等效,成为字符串的别名,这种用来代表变量的符号称为替代符号。号称为替代符号。 当汇编器遇到替代符号时,将用字符串值替代符号当汇编器遇到替代符号时,将用字符串值替代符号。和符号常数不同,替代符号可以被重新定义。可在。和符号常数不同,替代符号可以被重新定义。可在程序中的任何地方将变量赋给替代符号。程序中的任何地方将变量赋给替代符号。 例如:例如: .asg.asg ""high"high" ,, AR2 AR2 ;;寄存器寄存器 AR2AR2

Page 114: 第5章   TMS320C54x 软件开发

55..55..44 汇编源程序中的表达式 汇编源程序中的表达式 表达式可以是常数、符号,或者是由算术运算符分表达式可以是常数、符号,或者是由算术运算符分开的一系列常数和符号。开的一系列常数和符号。 有效表达式的值有效表达式的值 : : -- 3232 768768~~3232 767 767 影响表达式的主要因素:影响表达式的主要因素: ① ① 圆括号圆括号 ( )( ) 。圆括号内的表达式最先计算;。圆括号内的表达式最先计算; 不能用大括号不能用大括号 { }{ } 或中括号或中括号 [ ][ ] 代替圆括号代替圆括号 ( )( ) 。。 ② ② 优先级。’优先级。’ C54xC54x 汇编器使用与汇编器使用与 CC 语言相似的语言相似的

优 先级,优先级高的先计算;优 先级,优先级高的先计算; ③③ 从左到右运算。具有相同的优先级,按从左 从左到右运算。具有相同的优先级,按从左

到右的顺序计算。 到右的顺序计算。

序号 符 号 运算操作 求值顺序1 + - ~ ! 取正、取负、按位求补、逻辑负 从右至左2 * / % 乘法、除法、求模 从左至右3 + - 加法、减法 从左至右4 ^ 指数 从左到右 5 << >> 左移、右移 从左至右6 < <= 小于、小于等于 从左至右7 > >= 大于、大于等于 从左至右8 != = 不等于、等于 从左至右9 & 按位与运算 从左至右

10 ∧ 按位异或运算 从左至右11 | 按位或运算 从左至右

1.1. 运算符运算符

Page 115: 第5章   TMS320C54x 软件开发

2.2. 合格的表达式 合格的表达式 某些汇编器要求合格的表达式作为操作数。操作数某些汇编器要求合格的表达式作为操作数。操作数是汇编时间常数或链接时可重定位的符号。是汇编时间常数或链接时可重定位的符号。 合格的表达式是指表达式中的符号或汇编时间常数合格的表达式是指表达式中的符号或汇编时间常数在表达式之前就已经被定义在表达式之前就已经被定义。。

合格的表达式的计算必须是绝对的。合格的表达式的计算必须是绝对的。

Page 116: 第5章   TMS320C54x 软件开发

【例【例 55-15-15 】】 有效定义的表达式。有效定义的表达式。 ..datadata label1 .word 0label1 .word 0 .word 1.word 1 .word 2.word 2 label2 .word 3label2 .word 3 X .set 50hX .set 50h goodsym1 .set l00hgoodsym1 .set l00h ++ X X goodsym2 .set $ goodsym2 .set $ goodsym3 .set label1 goodsym3 .set label1 goodsym4 .set label2-goodsym4 .set label2-label1label1

; ; 将将 1616 位值位值 0,1,20,1,2 放入标号放入标号为为 label1label1 的当前段连续字中的当前段连续字中

; ; 有效定义的表达式有效定义的表达式; ; 引用已定义的所有局部标号引用已定义的所有局部标号; ; 有效定义的表达式有效定义的表达式

; ; 定义定义 XX 的值的值; ; 将将 33 放入标号为放入标号为 label2label2 的的字中字中

Page 117: 第5章   TMS320C54x 软件开发

【例【例 -16-16】】无无效定义的表达式。效定义的表达式。 .global Y .global Y badsym1 .set Y badsym1 .set Y badsym2 .set 50hbadsym2 .set 50h + + Y Y badsym3 .set 50hbadsym3 .set 50h ++ Z Z Z .set 60hZ .set 60h

; ; 定义定义 YY 为全局外部符为全局外部符号号; ; YY 在当前文件中未定在当前文件中未定义义 ; ; 无效的表达式无效的表达式; ; 无效的表达式,无效的表达式, ZZ 还未定义还未定义; ; 定义定义 ZZ ,,但应在表达式使用之前但应在表达式使用之前

Page 118: 第5章   TMS320C54x 软件开发

3.3. 表达式上溢和下溢 表达式上溢和下溢 汇编时执行了算术操作以后,汇编器检查上溢和下汇编时执行了算术操作以后,汇编器检查上溢和下溢的条件。当出现上溢或下溢时,汇编器会发出一个溢的条件。当出现上溢或下溢时,汇编器会发出一个值被截断了的警告。值被截断了的警告。 汇编器不检查乘法的溢出状态。 汇编器不检查乘法的溢出状态。

Page 119: 第5章   TMS320C54x 软件开发

4.4. 可重新定位符号和合法表达式 可重新定位符号和合法表达式 对于绝对符号、可重新定位符号以及外部符号的有对于绝对符号、可重新定位符号以及外部符号的有效操作,可参见下表。 效操作,可参见下表。

带有绝对符号和可重新定位符号的表达式 如果 A 为… 并且 B 为… A+B 为… A-B 为…

绝对绝对绝对

可重新定位可重新定位 可重新定位

外部 外部 外部

绝对 外部

可重新定位 绝对

可重新定位 外部 绝对

可重新定位 外部

绝对外部

可重新定位可重新定位

非法非法 外部非法非法

绝对非法非法

可重新定位绝对非法外部非法非法

Page 120: 第5章   TMS320C54x 软件开发

返回本节

表达式不能包含可重新定位符号和外部符号的乘表达式不能包含可重新定位符号和外部符号的乘或除;或除; 表达式中不能含表达式中不能含有有对其他的段对其他的段为为可重新定位的符可重新定位的符号号;; 用用 ..globalglobal伪指令定义为全局的符号和寄存器也可伪指令定义为全局的符号和寄存器也可以用在表达式中。这些符号和寄存器被声明为外部以用在表达式中。这些符号和寄存器被声明为外部符号符号;; 可重新定位的寄存器也可以用在表达式中,这些可重新定位的寄存器也可以用在表达式中,这些寄存器的地址相对于定义它们的寄存器段是可重新寄存器的地址相对于定义它们的寄存器段是可重新定位的,除非将它们声明为外部符号。定位的,除非将它们声明为外部符号。

Page 121: 第5章   TMS320C54x 软件开发

例例如:在下面的程序中,如:在下面的程序中,使用使用了了 44个定义在相同个定义在相同段的符号。段的符号。 ..global extern_1global extern_1 intern_1intern_1 : : .word ‘’’D’.word ‘’’D’ LAB1LAB1 : : .set 2.set 2 intern_2intern_2 : : .word 3.word 3 LD #LAB1+((5+4)*3),ALD #LAB1+((5+4)*3),A LD #LAB1+3+(4*7),ALD #LAB1+3+(4*7),A

..global global extern_1extern_1 intern_1intern_1 : : .word ‘’’D’.word ‘’’D’ LAB1LAB1 : : .set 2.set 2 intern_2intern_2 : : .word 3.word 3 LD #LD #LAB1LAB1+((5+4)*3),A+((5+4)*3),A LD #LD #LAB1LAB1+3+(4*7),A+3+(4*7),A

;定义在外部;定义在外部的全局符号的全局符号

;定义在;定义在现行模块中,可重新定位现行模块中,可重新定位

;; LAB1=2LAB1=2 ,,绝对符号绝对符号

;定义在;定义在现行模块中,可重新定位现行模块中,可重新定位

;; LAB1LAB1 为为绝对符绝对符号,号, AA==2929 ;; LAB1LAB1 为绝对符为绝对符号,号, AA==3333

Page 122: 第5章   TMS320C54x 软件开发

所有合法表达式可以化简为两种形式:所有合法表达式可以化简为两种形式: ①① 可重新定位符号可重新定位符号±±绝对符号;绝对符号; ②② 绝对符号。绝对符号。 单操作数运算仅能应用于绝对符号,不能应用于可单操作数运算仅能应用于绝对符号,不能应用于可重新定位符号。重新定位符号。 表达式简化为仅含有可重新定位符号是非法的。表达式简化为仅含有可重新定位符号是非法的。

Page 123: 第5章   TMS320C54x 软件开发

【例【例 55-17-17 】 】 判断下列指令中表达式的合法性。判断下列指令中表达式的合法性。 LDLD extern_1extern_1--1010 ,, BB

LDLD 1010--extern_1extern_1 ,, BB

LDLD -( -(intern_1intern_1)) ,, BB

LDLD extern_1/10extern_1/10 ,, BB

LDLD intern_1 + extern_1intern_1 + extern_1 ,, BB

可重新定位可重新定位 合法合法

不可将重新定位符号变负不可将重新定位符号变负

可重新定位符号不可变负可重新定位符号不可变负 非非法法

可重新定位符号不可乘除可重新定位符号不可乘除 非非法法

可重新定位可重新定位 ++ 可重新定位可重新定位 == 非非法法

非非法法

非非法法

Page 124: 第5章   TMS320C54x 软件开发

【例【例 55-18-18 】 】 判断下列指令中表达式的合法性。判断下列指令中表达式的合法性。 LD intern_1 - intern_2 + extern_1LD intern_1 - intern_2 + extern_1 ,, BB

LD intern_1 + intern_2 + extern_1LD intern_1 + intern_2 + extern_1 ,, BB

LD intern_1 + extern_1 - intern_2LD intern_1 + extern_1 - intern_2 ,, BB

可重新定位可重新定位 可重新定位可重新定位可重新定义可重新定义 -- 可重新定义可重新定义 == 绝对符号绝对符号 绝对符号绝对符号 可重新定位可重新定位绝对符号绝对符号 ++ 可重新定位可重新定位合法合法

可重新定义可重新定义 ++ 可重新定义可重新定义 == 非法非法非法非法

可重新定义可重新定义 ++ 可重新定义可重新定义 == 非法非法非法非法

Page 125: 第5章   TMS320C54x 软件开发

5.6 TMS320C54x C 语言编程 5.6.1 存储器模式 5.6.2 寄存器规则 5.6.3 函数调用规则 5.6.4 中断处理 5.6.5 表达式分析

返回首页

Page 126: 第5章   TMS320C54x 软件开发

5.6.1 存储器模式1 .段 C54x 将存储器处理为程序存储器和数据存储器两个线性块。程序存储器包含可执行代码;数据存储器主要包含外部变量、静态变量和系统堆栈。编译器的任务是产生可重定位的代码,允许链接器将代码和数据定位进合适的存储空间。 C 编译器 对 C 语 言 编 译 后除了生 成 3 个 基 本 段 ,即 .text 、 .data 、 .bss 外 , 还 生成 .cinit 、 .const 、 .stack 、 .sysmem 段。

Page 127: 第5章   TMS320C54x 软件开发

2 . C/C++ 系统堆栈 .stack 不同于 DSP 汇编指令定义的堆栈。 DSP 汇编程序中要将堆栈指针 SP 指向一块 RAM ,用于保存中断、调用时的返回地址,存放 PUSH 指令的压栈内容。 .stack 定义的系统堆栈实现的功能是保护函数的返回地址,分配局部变量,在调用函数时用于传递参数,保护临时结果。 .stack 定义的段大小(堆栈大小)可用链接器选项 -stack size设定,链接器还产生一个全局符号 _ _STACK_SIZE ,并赋给它等于堆栈长度的值,以字为单位,缺省值为 1K 。

Page 128: 第5章   TMS320C54x 软件开发

3 .存储器分配( 1 )运行时间支持函数。 ( 2 )动态存储器分配。 ( 3 )静态和全局变量的存储器分配。( 4 )位域 /结构的对准。

返回本节

Page 129: 第5章   TMS320C54x 软件开发

5.6.2 寄存器规则 寄存器规则明确了编译器如何使用寄存器以及在函数调用过程中如何保护寄存器。( 1 )辅助寄存器 ( 2 )堆栈指针 SP ( 3 ) ARP ( 4 )在默认情况下,编译器总是假定 ST1 中的 OVM 在硬件复位时被清 0 。若在汇编代码中对 OVM置位为 1 ,返回到 C环境时必须复位。( 5 )寄存器变量

返回本节

Page 130: 第5章   TMS320C54x 软件开发

5.6.3 函数调用规则( 1 )局部帧的产生 ( 2 )参数传递 ( 3 )函数的返回

返回本节

Page 131: 第5章   TMS320C54x 软件开发

5.6.4 中断处理( 1 )中断的使能和屏蔽必须由程序员自己来设置。 ( 2 )中断程序没有参数传递,即使说明,也会被忽略( 3 )中断处理程序不能被正常的 C 程序调用。( 4 )为了使中断程序与中断一致,在相应的中断矢量中必须放置一条转移指令,可以用 .sect 汇编伪指令建立一个简单的跳转指令表来完成此项功能。

Page 132: 第5章   TMS320C54x 软件开发

( 5 )在汇编语言中,注意在符号名前面加上一个下划线,例如 c_int00记为 _ c_int00 。

( 6 )中断程序使用的所有寄存器,包括状态寄存器和程序中调用函数使用的寄存器都必须予以保护。( 7 ) TMS320C54x C 编译器将 C 语言进行了扩展,中断可以利用 interrupt 关键字由 C/C++函数直接处理。

返回本节

Page 133: 第5章   TMS320C54x 软件开发

5.6.5 表达式分析 当 C 程序中需要计算整型表达式时,必须注意以下几点:( 1 )算术上溢和下溢。 ( 2 )整除和取模。 ( 3 ) C 代码对 16 位乘法结果高 16 位的访问。

返回本节

Page 134: 第5章   TMS320C54x 软件开发

5.7 用 C 语言和汇编语言混合编程 5.7.1 独立的 C 模块和汇编模块接口 5.7.2 从 C 程序中访问汇编程序变量 5.7.3 在 C 程序中直接嵌入汇编语句

返回首页

Page 135: 第5章   TMS320C54x 软件开发

5.7.1 独立的 C 模块和汇编模块接口 在编写独立的汇编程序时,必须注意以下几点:( 1 )不论是用 C 语言编写的函数还是用汇编语言编写的函数,都必须遵循寄存器使用规则。( 2 )必须保护函数要用到的几个特定寄存器。 ( 3 )中断程序必须保护所有用到的寄存器。( 4 )从汇编程序调用 C函数时,第一个参数(最左边)必须放入累加器 A 中,剩下的参数按自右向左的顺序压入堆栈。

Page 136: 第5章   TMS320C54x 软件开发

( 5 )调用 C函数时,注意 C函数只保护了几个特定的寄存器,而其他是可以自由使用的。( 6 )长整型和浮点数在存储器中存放的顺序是低位字在高地址,高位字在低地址。( 7 )如果函数有返回值,返回值存放在累加器 A 中。 ( 8 )汇编语言模块不能改变由 C 模块产生的 .cinit段,如果改变其内容将会引起不可预测的后果。

Page 137: 第5章   TMS320C54x 软件开发

( 9 )编译器在所有标识符(函数名、变量名等)前加下划线“ _” 。 ( 10 )任何在汇编程序中定义的对象或函数,如果需要在 C 程序中访问或调用,则必须用汇编指令 .

global 定义。 ( 11 )编辑模式 CPL 指示采用何种指针寻址,如

果 CPL=1 ,则采用堆栈指针 SP 寻址;如果CPL=0 ,则选择页指针 DP 进行寻址。

返回本节

Page 138: 第5章   TMS320C54x 软件开发

5.7.2 从 C 程序中访问汇编程序变量 从 C 程序中访问在汇编程序中定义的变量或常数,可以分为以下 3 种情况:( 1 )访问在 .bss 块中定义的变量 ( 2 )对于访问不在 .bss 块中定义的变量 ( 3 )对于在汇编程序中用 .set 和 .global 伪指令定义的全局常数,也可以使用特殊的操作从 C 程序中访问它们。

返回本节

Page 139: 第5章   TMS320C54x 软件开发

5.7.3 在 C 程序中直接嵌入汇编语句 在 C 程序中嵌入汇编语句是一种直接的 C 模块和汇编模块接口方法。采用这种方法一方面可以在

C 程序中实现用 C 语言难以实现的一些硬件控制功能。另一方面,也可以用这种方法在 C 程序中的关键部分用汇编语句代替 C 语句以优化程序。 采用这种方法的一个缺点是它比较容易破坏 C环境,因为 C 编译器在编译嵌入了汇编语句的 C 程序时并不检查或分析所嵌入的汇编语句。

返回本节