版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
共96页1第5章ARM汇编本章主要内容1、汇编、汇编器和汇编语言程序的基本概念2、ARM汇编语言中的符号3、ARM的伪指令、宏4、汇编语句格式共96页1第5章ARM汇编本章主要内容1、汇编、汇编器和共96页25、ARM汇编语言中的表达式及运算符共96页25、ARM汇编语言中的表达式及运算符共96页35.1汇编器与汇编语言ARM编译器支持汇编语言的程序设计和C/C++语言的程序设计,以及两者两者的混合编程。1、什么叫汇编语言
汇编语言(AssemblyLanguage)是面向机器的程序设计语言。共96页35.1汇编器与汇编语言ARM编译器支持共96页4
在汇编语言中,用助记符(Memoni)代替操作码,用地址符号(Symbol)或标号(Label)代替地址码。这样用符号代替机器语言的二进制码,就把机器语言变成了汇编语言。于是汇编语言亦称为符号语言。2、汇编语言的优点共96页4在汇编语言中,用助记符(Memoni)代替共96页5
汇编语言比机器语言易于读写、易于调试和修改,同时也具有机器语言执行速度快,占内存空间少等优点,但在编写复杂程序时具有明显的局限性,汇编语言依赖于具体的机型,不能通用,也不能在不同机型之间移植。3、什么叫汇编器共96页5汇编语言比机器语言易于读写、易于调试和修改共96页6
使用汇编语言编写的程序,机器不能直接识别,要由一种程序将汇编语言翻译成机器语言,这种起翻译作用的程序叫汇编程序(也叫汇编器),汇编程序是系统软件中语言处理系统软件。4、什么叫汇编
汇编程序把汇编语言翻译成机器语言的过程称为汇编。共96页6使用汇编语言编写的程序,机器不能直接识别共96页75、汇编语言程序、汇编器和机器码程序之间的关系共96页75、汇编语言程序、汇编器和机器码程序之间的关系共96页86、什么是伪指令
人们设计了一些专门用于指导汇编器进行汇编工作的指令,由于这些指令不形成机器码指令,它们只是在汇编器进行汇编工作的过程中起作用,所以被叫做伪指令。7、什么叫宏共96页86、什么是伪指令人们设计了一些专门用共96页9
为了提高编程效率和增强程序的可读性,有设计了一些宏。8、什么叫汇编语言程序
用汇编语言编写的程序叫做汇编语言程序。9、什么叫目标程序
自源程序翻译成的机器码程序就叫做目标程序。共96页9为了提高编程效率和增强程序的可读性共96页105.2ARM伪指令
在ARM汇编程序语言中,有如下几种伪指令:
段定义、符号定义、数据定义、数据缓冲池定义、数据表定义、数据空间分配、汇编控制伪指令以及其他伪指令。5.2.1段定义伪指令共96页105.2ARM伪指令在ARM汇编程序语共96页11
段定义伪指令的格式为:AREA<sectionname>{<attr>},{,<attr>},…
Sectionname:段名,若段名以数字开头,则必须用符号“|”扩起来,如|1_test|。
attr:属性字段,多个属性字段用逗号分隔。共96页11段定义伪指令的格式为:Sectionn共96页12属性含义备注CODE代码段默认读/写属性为READONLYDATA数据段默认属性为READWRITEREADONLY本段为只读READWRITE本段为可读可写ALIGN表达式多源文件共享段ELF的代码段和数据段为字对齐COMMON多源文件共享段共96页12属性含义备注CODE代码段默认读/写属性为REA共96页13
AREAInit,CODE,READONLY
…………;程序段
该伪指令定义了一个代码段,段名为Init,属性为只读。
一个汇编语言程序至少要有一个段。5.2.2符号定义伪指令
符号的命名由编程者决定,但必须遵循以下约定:共96页13AREAInit,CODE,READO共96页14(1)符号区分大小写,同名的大、小写符号会被编译器认为是两个不同的符号。(2)符号在其作用范围内必须唯一。(3)自定义的符号不能与系统保留字相同。(4)符号不应与指令或伪指令同名1、定义全局变量伪指令GBLA、GBLL和GBLS共96页14(1)符号区分大小写,同名的大、小写符号会被编译共96页15GBLA、GBLL和GBLS伪指令用于定义一个ARM程序中的全局变量,并将其初始化。GBLA(GBLL和GBLS)<varible>
varible为变量名称。GBLA定义一个全局数字变量,其默认初值为0。共96页15GBLA、GBLL和GBLS伪指令用于定共96页16GBLL定义一个全局逻辑变量,其默认初值为F(假)。GBLS定义一个全局字符串变量,其默认初值为空。GBLATest1;定义一个全局数字变量,变量名为Test1GBLLTest2;定义一个全局逻辑变量,变量名为Test2共96页16GBLL定义一个全局逻辑变量,其默认初值为F(假共96页17GBLSTest1;定义一个全局字符串变量,变量名为Test3
全局变量的变量名在整个程序范围内必须具有唯一性。2、定义局部变量位指令LCLA、LCLL和LCLSLCLA、LCLL和LCLS伪指令用于定义一个ARM程序中的局部变量,并将其初始化。共96页17GBLSTest1;定义一个全局字符串变共96页18LCLA(LCLL和LCLS)<varible>
varible为变量名称。LCLA定义一个局部数字变量,其默认初值为0。LCLL定义一个局部逻辑变量,其默认初值为F(假)。LCLS定义一个局部字符串变量,其默认初值为空。共96页18LCLA(LCLL和LCLS)<varible共96页19LCLATest4;定义一个局部数字变量,变量名为Test4LCLLTest5;定义一个局部逻辑变量,变量名为Test5LCLSTest6;定义一个局部字符串变量,变量名为Test6
局部变量的变量名在变量作用范围内必须具有唯一性。共96页19LCLATest4;定义一个局部数字变量共96页20
在默认情况下,局部变量只在定义该变量的程序段内有效。3、变量赋值伪指令SETA、SETL和SETS
伪指令SETA、SETL和SETS用于给一个已经定义的全局变量或局部变量进行赋值。Test1SETA0xAA;将Test1变量赋值为0xAA。共96页20在默认情况下,局部变量只在定义该变共96页21Test2SETL{TRUE};将Test2变量赋值为真。Test3SETS“Testing”;将Test3变量赋值为“Testing”
。Test4SETA0xBB;将Test4变量赋值为0xBB。Test5SETL{TRUE};将Test5变量赋值为真。共96页21Test2SETL{TRUE};将T共96页22Test6SETS“Testing”;将Test6变量赋值为“Testing”
。4、定义寄存器列表伪指令RLIST
指令LDM/STM需要使用一个比较长的寄存器列表,使用伪指令RLIST可对一个列表定义一个统一的名称。
<name>RLIST<{list}>
name为表名成;{list}为寄存器列表。共96页22Test6SETS“Testing”;共96页23
RegListRLIST{R0-R5,R8,R10};将寄存器列表名称定义为RegList。
列表中的寄存器访问次序根据寄存器的编号由低到高,而与列表中的寄存器陪列次序无关。5.2.3程序中的标号
在汇编语言中用来表示地址的符号就叫做标号。共96页23RegListRLIST{R0-R5,R8共96页24
LDRR0,#0x3FF5000target1LDRR1,0xFFSTRR1,[R0]LDRR0,#0x3FF5008LDRR1,0x01STRR1,[R0]Btarget1;转移到target1位置上运行共96页24共96页25
这里的target1就是标号。
在ARM汇编中,根据用途不同标号主要有以下2种:(1)目标地址标号
写在一条指令前面的标号。(2)数据或数据区首地址标号
写在数据或数据区定义伪指令前面的标号。共96页25这里的target1就是标号。共96页265.2.4数据定义伪指令
该指令的功能就是为指定的数据分配存储单元,以及用该数据对已分配存储单元进行初始化。1、DCBDCB伪指令用于分配一片连续的以字节为单位的存储区域,并用指定的表达式对其进行初始化。共96页265.2.4数据定义伪指令该指令共96页27
{<label>}DCB<expr>label为标号,为存储区域的首地址(可选)。expr为表达式,为从标号开始存放的数据。该表达式可以为0~255的数字或字符串。
Dat1DCB0x7EDCB也可用“=”代替,即Dat1=0x7E共96页27{<label>}DCB<expr>共96页282、DCW(或DCWU)DCW(或DCWU)伪指令用于为数据分配一片连续的半字存储单元,并用表达式对其进行初始化。<label>DCW(或DCWU)<expr>
用DCW分配的字存储单元是严格按半字对齐的,而用DCWU分配的字存储单元并不严格按半字对齐。共96页282、DCW(或DCWU)DCW(或DCW共96页293、DCD(或DCDU)DCD(或DCDU)伪指令用于分配一片连续的字存储单元,并用伪指令中指定的表达式初始化。
DataTestDCW1,2,3;分配一片连续的半字存储单元并初始化
<label>DCD(或DCDU)<expr>共96页293、DCD(或DCDU)DCD(或DCD共96页30
用DCD分配的字存储单元是字对齐的,而用DCDU分配的字存储单元并不严格要求字对齐。
DataTestDCD4,5,6;分配一片连续的存储单元并初始化DCD也可用“&”代替。4、DCFD(或DCFDU)共96页30用DCD分配的字存储单元是字对齐的,而用共96页31DCFD(或DCFDU)伪指令用于为双精度的浮点数分配一片连续的字存储单元,并用伪指令中指定的表达式初始化。每个双精度的浮点数占据两个字单元。<label>DCFD(或DCFDU)<expr>
用DCFD分配的字存储单元是字对齐的而用DCFDU分配的字存储单元并不严格字对齐。共96页31DCFD(或DCFDU)伪指令用于为双精共96页32
FDataTestDCFD2E115,-5E7;分配一片连续的字存储单元,并初始化为指定的双精度数。5、DCFS(或DCFSU)DCFS(或DCFSU)伪指令用于为单精度的浮点数分配一片连续的字存储单元,并用伪指令中指定的表达式初始化。每个单精度浮点熟占据一个字单元。共96页32FDataTestDCFD2E115,-5共96页33<label>DCFS(或DCFSU)<expr>
用DCFS分配的字存储单元是字对齐的而用DCFSU分配的字存储单元并不严格字对齐。
FDataTestDCFS2E5,-5E-7;分配一片连续的字存储单元,并初始化为指定的单精度数。6、DCQ(或DCQU)共96页33<label>DCFS(或DCFSU)<共96页34DCQ(或DCQU)伪指令用于分配一片以8字节为单位的连续存储区域,并用伪指令中指定的表达式初始化。<label>DCQ(或DCQU)<expr>
用DCQ分配的存储单元是字对齐的,而用DCQU分配的字存储单元并不严格字对齐。共96页34DCQ(或DCQU)伪指令用于分配一片以共96页35
DataTestDCQ100;分配一片连续的存储单元并初始化为指定的值。7、SPACESPACE伪指令用于分配一片连续的存储区域并初始化为0。<label>SPACE<expr>
表达式为要分配的字节数,SPACE也可用“%”代替。共96页35DataTestDCQ100;分配一片共96页36
DataSpaceSPACE100;分配连续的100字节的存储单元并初始化为0。8、LTORG
伪指令LTORG用来说明某个存储区域为一个用来暂存数据的数据缓冲区,也叫文字迟或数据缓冲池。大的代码段也可以使用多个数据缓冲池。共96页36DataSpaceSPACE100;分共96页37
AREAexample,CODE,READONLYStartBLFunc1
…Func1LDRR1,#0x800MOVPC,LRLTORG;定义数据缓冲池的开始位置
DateSPACE40;数据缓冲池有40个被初
END;始化为0的字节9、MAP和FIELD共96页37共96页38
在应用程序中经常使用一种如图所示的表:共96页38在应用程序中经常使用一种如图所示共96页39MAP可以用“^”代替。MAP用于定义一个结构化的内存表的首地址。语法格式如下:
MAP<expr>{,<baseregister>}
expr为结构化表首地址。可以为标号或数字表达式。
baseregister为基址寄存器(可选项)。基址寄存器的值与expr的值之和就是表首地址。共96页39MAP可以用“^”代替。MAP用共96页40MAPfun;fun就是内存表的首地址MAP0x100,R9;内存表的首地址为R9+0X100MAP通常和FIELD伪指令相配合来定义一个结构化的内存表。FIELD伪指令用于定义一个结构化内存表中的数据域。<label>FIELD<expr>
label为标号。共96页40MAPfun;fun就是内存表的首地址共96页41
expr为表达式。它的值为数据域所占的字节数。FIELD伪指令与MAP伪指令配合使用来定义结构化的内存表。MAP伪指令定义内存表的首地址;FIELD伪指令定义内存表中各个数据域,并可以为每个数据域指定一个标号供其他指令引用。共96页41expr为表达式。它的值为数据域所占的字节数。共96页42
MAP0X100;定义结构化内存表首地址为0X100AFIELD16;定义A的长度为16字节,位置为0X100BFIELD32;定义B的长度为32字节,位置为0X110SFIELD256;定义S的长度为256字节,位置为0X130
注意:MAP和FIELD伪指令仅用于定义数据结构,并不实际分配存储单元。FIELD也可用“#”代替。5.2.5汇编控制伪指令共96页42MAP0X100;定义结构化内存表首地共96页431、IF、ELSE和EDNIFIF、ELSE和ENDIF伪指令能根据条件的成立与否决定是否执行某个程序段。IF逻辑表达式程序段1ELSE
程序段2ENDIF共96页431、IF、ELSE和EDNIFIF、EL共96页44IF、ELSE、ENDIF伪指令可以嵌套使用。
GBLLTest;声明一个全局逻辑变量Test
….IFTest=TRUE
程序段1ELSE
程序段2ENDIF2、WHILE和WEND共96页44IF、ELSE、ENDIF伪指令可以嵌套使用。共96页45WHILE和WEND伪指令根据条件的成立与否决定是否重复汇编一个程序段。WHILE逻辑表达式程序段WEND
若WHILE后面的逻辑表达式为真,则重复汇编该程序段,直到逻辑表达式为假。共96页45WHILE和WEND伪指令根据条件的成立共96页46WHILE和WEND伪指令可以嵌套使用。GBLACounter;声明一个全局数字变量CounterCounterSETA3;赋值
…..WHILECounter<10
程序段
WEND5.2.6其它常用的伪指令共96页46WHILE和WEND伪指令可以嵌套使用。共96页471、定义对齐方式伪指令ALIGN
使用ALIGN伪指令可用添加填充字节的方式,使当前位置实现某种对齐方式。ALIGN{表达式{,偏移量}}
对齐方式为2表达式的值。偏移量为一个数字表达式,若使用该字段,则当前位置的对齐方式为2表达式的值+偏移量。共96页471、定义对齐方式伪指令ALIGN使用AL共96页48
;指定后面的指令为8字节对齐
AREAInit,CODE,READONLY,ALIGN=3
代码段
END2、CODE16和CODE32
CODE16用来表明其后的指令均为16位Thumb指令;CODE32伪指令则表明其后面的指令均为32位ARM指令。共96页48;指定后面的指令为8字节对齐2、CODE16和共96页49
CODE16(或CODE32)
AREAInit,CODE,READONLY
…..CODE32LDRR0,#NEXT+1BXR0
…CODE16NEXTLDRR3,#0X3FF
…END共96页49CODE16(或CODE32)AREAIn共96页503、定义程序入口点伪指令ENTRYENTRY伪指令用于指定汇编程序的入口点。
ENTRY
AREAInit,CODE,READONLYENTRY;
…..共96页503、定义程序入口点伪指令ENTRYENT共96页514、汇编结束伪指令ENDEND伪指令用于通知编译器汇编工作到此结束,不再往下汇编了。
END
AREAInit,CODE,READONLY
…END共96页514、汇编结束伪指令ENDEND伪指令用于共96页525、等效伪指令EQUEQU伪指令用于为程序中的常量、标号等定义一个等效的字符名字,其作用类似于C语言中的#define。
名称EQU表达式{,类型}EQU也可用“*”代替。共96页525、等效伪指令EQUEQU伪指令用于为程共96页53
由EQU伪指令定义的字符名称,当其表达式为32位常量时,可以指定表达式的数据类型,有以下三种类型:CODE16、CODE32和DATA。
TestEQU50;定义标号Test的值为50AddrEQU0x55,CODE32;定义Addr的值为0x55,其该处为32位的ARM指令共96页53由EQU伪指令定义的字符名称,当其表达式共96页546、外部可引用符号声明伪指令EXPORT(或GLOBAL)
用伪指令EXPORT可以声明一个其他源文件可引用的符号,这种符号也叫做外部可引用符号。EXPORT符号{[WEAK]}EXPORT可用GLOBAL代替。共96页546、外部可引用符号声明伪指令EXPORT(或GL共96页55
标号在程序中区分大小写,[WEAK]选项声明其他的同名标号优先于该标号被引用。
AREAInit,CODE,READONLYEXPORTStest
…END7、IMPORT共96页55标号在程序中区分大小写,[WEAK]选项共96页56
当在一个源文件中需要使用另外一个源文件的外部可引用符号时,在被引用的符号前面必须使用伪指令IMPORT对其进行声明。IMPORT符号{[WEAK]}
如果源文件声明了一个引用符号,则无论当前源文件中程序是否真正地使用了该符号,该符号均会被加入到当前源文件的符号表中。共96页56当在一个源文件中需要使用另外一个源文件的共96页57[WEAK]选项表示当前所有的源文件都没有定义这样一个标号时,编译器也不报错,并在多数情况下将该标号置为0。但该标号被B或BL指令所引用时,则将B或BL指令置为NOP操作。
AREAInit,CODE,READONLYIMPORTMain
…END共96页57[WEAK]选项表示当前所有的源文件都没共96页588、EXTERNEXTERN伪指令与IMPORT伪指令的功能基本相同,但如果当前源文件中的程序实际并未使用该指令,则该符号不会加入到当前源文件的符号表中。
其它与IMPORT相同。9、GET(或INCLUDE)共96页588、EXTERNEXTERN伪指令与IM共96页59GET伪指令用于将一个源文件包含到当前的源文件中,并将被包含的源问在当前位置进行汇编。GET文件名
可以使用INCLUDE代替GET。GET伪指令只能用于包含源文件,包含目标文件则需要使用INCBIN伪指令。共96页59GET伪指令用于将一个源文件包含到当前的共96页60
AERAInit,CODE,READONLYGETa1.sGETc:\a2.s
…
END10、INCBININCBIN伪指令用于将一个目标文件或数据文件包含到当前的源文件中,被包含共96页60AERAInit,CODE,READ共96页61的文件不做任何变动地存放在当前文件中,编译器从其后开始继续处理。
INCBIN文件名
AREAInit,CODE,READONLYINCBINa1.datINCBINc:\a2.txt
…END共96页61的文件不做任何变动地存放在当前文件中,编译器从其共96页6211、RNRN伪指令用于给一个寄存器定义一个别名,一提高程序的可读性。
名称RN表达式
名称为给寄存器定义的别名,表达式为寄存器的编码。
TempRNR0;将R0定义一个别名Temp共96页6211、RNRN伪指令用于给一个寄存器定义共96页6312、ROUT
ROUT伪指令用于给一个局部变量定义作用范围。
名称ROUT
在程序中未使用该伪指令时,局部变量的作用范围为所在的AREA;而使用ROUT后,局部变量的作用范围为当前ROUT和下一个ROUT之间。共96页6312、ROUTROUT伪指令用于给一个局共96页645.3宏与宏指令5.3.1宏1、MACRO和MENDMACRO和MEND伪指令可以为一个程序段定义一个名称。这样,在汇编语言应用程序中就通过这个名称来使用它所代表的程序段,即当程序做汇编时,该名称将被替换为其所代表的程序段。共96页645.3宏与宏指令5.3.1宏1、MACR共96页65MACRO$标号宏名$参数1,$参数2,…..程序段(宏定义体)MEND$标号:主标号,宏内的所有其它标号必须由主标号组成。宏名:宏名称,为宏在程序中的引用名。$参数1,$参数2:宏中可以使用的参数。共96页65MACRO$标号:主标号,宏内的所有其它标号必须共96页66
宏中的所有标号必须在前面冠以符号“$”。
MACRO;宏定义指令$MDATAMAXNUM$NUM1,$NUM2;主标号,宏名,参数语句段$MDATD.MAY1;宏内标号语句段$MDATA.MAY2;宏内标号语句段
MEND;宏结束指令共96页66宏中的所有标号必须在前面冠以符号“$”。共96页672、MEXITMEXIT用于从宏定义中跳转出去。
MEXIT5.3.2宏指令
在ARM中,还有一种汇编器内置的无参数和标号宏——宏指令。
在汇编时,这些宏指令被替换成一条或两条真正的ARM或Thumb指令。共96页672、MEXITMEXIT用于从宏定义中跳共96页681、近地址读取指令ADRADR指令用于将一个近地址值传递到一个寄存器中。ADR{cond}<reg>,<expr>
reg为目标寄存器名称。
expr为表达式。该表达式通常是一个程序中表示一条指令存储位置的地址标号。共96页681、近地址读取指令ADRADR指令用于将共96页69
该指令的功能是把标号所表示的地址传递到目标寄存器中。
汇编器在汇编时,将把ADR伪指令替换成一条真正的ADD或SUB指令,以当前的PC值减去或加上expr与PC之间的偏移量得到标号的地址,并将其传递到目标寄存器。
startMOVR0,#10ADRR4,start共96页69该指令的功能是把标号所表示的地址传共96页70共96页70共96页71
由于指令ADD或SUB中对立即数的限制,因此标号地址就不能距离当前指令的地址(PC)过远。对于非字对齐地址来说,其距离必须在255字节以内;而对于字对齐地址来说,距离必须在1020字节一内。所以ADR叫做近地址读取指令。2、远地址读取指令ADRL
类似于ADR,但可以把更远的地址赋给目标寄存器。共96页71由于指令ADD或SUB中对立即数的限制,共96页72ADRL{cond}<reg>,<expr>
reg为目标寄存器名称。
expr为表达式,必须是64KB以内非字对齐地址,256KB以内的字对齐地址。
该指令只能在ARM状态下使用,在Thumb状态下不能使用。汇编时,ADRL伪指令由汇编器替换成两条合适的指令。共96页72ADRL{cond}<reg>,<expr共96页73
startMOVR0,#10ADRLR4,start+60000其中ADRL将被替换为如下两条指令:
ADDR4,PC,#0XE800ADDR4,R4,#0X2543
如果汇编器找不到合适的两条指令,将会报错。3、全范围地址读取指令LDR共96页73startMOVR0,#10其共96页74
LDR{cond}reg,={expr|label-expr}
reg:目标寄存器名称;
expr:32位常数;
label–expr:为基于PC地址表达式。
程序经常用这条指令把一个地址传递到寄存器reg中。汇编器再哦对这种指令进行汇编时,会根据指令中expr的值的大小来把这条指令替换为合适的指令。共96页74LDR{cond}reg,={expr|共96页75(1)当expr的值未超过MOV或MVN指令所限定的取值范围时,汇编器用ARM的MOV或MVN指令来取代宏指令LDR。(2)当expr的值超过MOV或MVN指令所限定的取值范围时,汇编器将常数expr放在由LTORG定义的文字缓冲池,同时用一条ARM的装载指令LDR来取代宏指令LDR,而这条装载LDR指令则用PC加偏移量的方法共96页75(1)当expr的值未超过MOV或MVN指令所限共96页76到文字缓冲池中把该常数读取到指令指定的寄存器。
由于这种指令可以传递一个32位地址,因此被叫做全范围地址读取指令。4、NOP
汇编器对NOP指令进行汇编时,会将其转换为:
MOVR0,R0共96页76到文字缓冲池中把该常数读取到指令指定的寄存器。共96页775.4汇编语言的规范5.4.1汇编语句格式ARM(Thumb)汇编语言的语句格式为:{<标号>}<指令或伪指令>{;注释}
在汇编语言程序设计中,每一条指令的助记符可以全部用大写或全部用小写,但不允许在一条指令中大小写混用。共96页775.4汇编语言的规范5.4.1汇编语句格共96页78
如果一条语句太长,则可将该长语句分成若干行来书写,每行的末尾用“\”来表示下一行与本行为同一条语句。5.4.2汇编语言的表达式和运算符
运算次序遵循如下的优先级:(1)优先级相同的双目运算符运算顺序为从左到右。共96页78如果一条语句太长,则可将该长语句分成若干共96页79(2)相邻的单目运算符的运算顺序为从右到左,且单目运算符的优先级高于其他运算符。(3)括号运算符的优先级最高。1、数字表达式及运算符(1)+、-、X、/及MOD算术运算符X+Y表示X与Y的和。共96页79(2)相邻的单目运算符的运算顺序为从右到左,且单共96页80(2)ROL、ROR、SHL及SHR移位运算符X-Y表示X与Y的差。
XXY表示X与Y的乘积。
X/Y表示X除以Y的商。X:MOD:Y表示X除以Y的余数。X:ROL:Y表示将X循环左移Y位。X:ROR:Y表示将X循环右移Y位。共96页80(2)ROL、ROR、SHL及SHR移位运算符共96页81X:SHL:Y表示将X左移Y位。
X:SHR:Y表示将X右移Y位。(3)AND、OR、NOT及EOR按位逻辑运算符
X:AND:Y表示将X和Y按位做逻辑“与”的操作。X:OR:Y表示将X和Y按位做逻辑“或”的操作。共96页81X:SHL:Y表示将X左移Y位。共96页82
:NOT:Y表示将Y按位做逻辑“非”的操作。X:EOR:Y表示将X和Y按位做逻辑“异或”的操作。2、逻辑表达式及运算符(1)=、>、<、>=、<=、/=、<>运算符
X=Y表示X等于Y。共96页82:NOT:Y表示将Y按位做逻辑“非”的共96页83
X>Y表示X大于Y。
X<Y表示X小于Y。
X>=Y表示X大于或等于Y。
X<=Y表示X小于或等于Y。
X/=Y表示X不等于Y。
X<>Y表示X不等于Y。共96页83X>Y表示X大于Y。X<共96页84(2)LAND、LOR、LNOT及LEOR运算符X:LAND:Y表示将X和Y做逻辑“与”的操作。X:LOR:Y表示将X和Y做逻辑“或”的操作。:LNOT:表示将Y做逻辑“非”的操作。X:LEOR:Y表示将X和Y做逻辑“异或”的操作。共96页84(2)LAND、LOR、LNOT及LEOR运算符共96页853、字符串表达式及运算符(1)LEN运算符(2)CHR运算符
编译器所支持的字符串最大长度为512字节。LEN运算符返回字符串的长度(字符数),以X表示字符串表达式。:LEN:X共96页853、字符串表达式及运算符(1)LEN运算符(2)共96页86CHR运算符将0~255之间的整数转换为一个字符,以M表示一个整数,其格式如下::CHR:M(3)STR运算符STR运算符将一个数字表达式或逻辑表达式转换为一个字符串。共96页86CHR运算符将0~255之间的整数转换为共96页87
对于数字表达式,STR运算符将其转换为一个以十六进制组成的字符串;对于逻辑表达式,STR运算符将其转换为字符串T或F。
:STR:X;X为数字表达式或逻辑表达式(4)LEFT运算符共96页87对于数字表达式,STR运算符将其转换为一共96页88LEFT运算符返回某个字符串左端的一个子集。
X:LEFT:YX为源字符串,Y为一个整数,表示要返回的字符个数。(5)RIGHT运算符RIGHT运算符返回某个字符串右端的一个子集。共96页88LEFT运算符返回某个字符串左端的一个子共96页89
X:RIGHT:YX为源字符串,Y为一个整数,表示要返回的字符个数。(6)CC运算符CC运算符用于将两个字符串连接成一个字符串。
X:CC:Y共96页89X:RIGHT:YX为共96页90
X:CC:YX为源字符串1,Y为源字符串2,CC运算符将Y连接到X的后面。4、与寄存器和程序计数器(PC)相关的表达式及运算符(1)BASE运算符BASE运算符返回基于寄存器的表达式中寄存器的编号。共96页90X:CC:YX为源字符共96页91
:BASE:XX为与寄存器相关的表达式。(2)INDEX运算符INDEX运算符返回基于寄存器的表达式中相对于其基址寄存器的便移量。
:INDEX:XX为与寄存器相关的表达式。共96页91:BASE:XX为与寄存共96页925、其它常用运算符(1)“?”运算符“?”运算符返回某代码行所生成的可执行代码的长度。
?X
返回定义符号X的代码行所生成的可执行代码的字节数。共96页925、其它常用运算符(1)“?”运算符共96页93(2)DEF运算符6、程序中的变量代换DEF运算符判断是否定义了某个符号。:DEF:X
如果符号X已经定义,则结果为真;否则为假。
程序中的变量可通过代换操作取得一个常量。代换操作符为“$”。共96页93(2)DEF运算符6、程序中的变量代换D共96页94
如果在数字变量前面有一个代换操作符“$”,则编译器会将该数字变量的值转换为十六进制的字符串,并将该十六进制的字符串代换“$”后的数字变量。
如果在逻辑变量前面有一个代换操作符“$”,则编译器会将该逻辑变量代换为它的取值(真或假)。共96页94如果在数字变量前面有一个代换操作符“$”共96页95
如果在字符串变量前面有一个代换操作符“$”,则编译器会将该字符串变量的值代换“$”后的字符串变量。LCLSs1;定义局部字符串变量S1和S2LCLSs2
s1SETS“Test!”
s2SETS“Thisisa$s1”
字符串变量S2的值为“ThisisaTest!”共96页95如果在字符串变量前面有一个代换操作符“$共96页96作业1、什么叫伪指令?它们有什么用途?2、ARM汇编中有哪些运算符?共96页96作业1、什么叫伪指令?它们有什么用途?2、ARM人有了知识,就会具备各种分析能力,明辨是非的能力。所以我们要勤恳读书,广泛阅读,古人说“书中自有黄金屋。”通过阅读科技书籍,我们能丰富知识,培养逻辑思维能力;通过阅读文学作品,我们能提高文学鉴赏水平,培养文学情趣;通过阅读报刊,我们能增长见识,扩大自己的知识面。有许多书籍还能培养我们的道德情操,给我们巨大的精神力量,鼓舞我们前进。人有了知识,就会具备各种分析能力,嵌入式系统基础第5章--ARM汇编课件共96页99第5章ARM汇编本章主要内容1、汇编、汇编器和汇编语言程序的基本概念2、ARM汇编语言中的符号3、ARM的伪指令、宏4、汇编语句格式共96页1第5章ARM汇编本章主要内容1、汇编、汇编器和共96页1005、ARM汇编语言中的表达式及运算符共96页25、ARM汇编语言中的表达式及运算符共96页1015.1汇编器与汇编语言ARM编译器支持汇编语言的程序设计和C/C++语言的程序设计,以及两者两者的混合编程。1、什么叫汇编语言
汇编语言(AssemblyLanguage)是面向机器的程序设计语言。共96页35.1汇编器与汇编语言ARM编译器支持共96页102
在汇编语言中,用助记符(Memoni)代替操作码,用地址符号(Symbol)或标号(Label)代替地址码。这样用符号代替机器语言的二进制码,就把机器语言变成了汇编语言。于是汇编语言亦称为符号语言。2、汇编语言的优点共96页4在汇编语言中,用助记符(Memoni)代替共96页103
汇编语言比机器语言易于读写、易于调试和修改,同时也具有机器语言执行速度快,占内存空间少等优点,但在编写复杂程序时具有明显的局限性,汇编语言依赖于具体的机型,不能通用,也不能在不同机型之间移植。3、什么叫汇编器共96页5汇编语言比机器语言易于读写、易于调试和修改共96页104
使用汇编语言编写的程序,机器不能直接识别,要由一种程序将汇编语言翻译成机器语言,这种起翻译作用的程序叫汇编程序(也叫汇编器),汇编程序是系统软件中语言处理系统软件。4、什么叫汇编
汇编程序把汇编语言翻译成机器语言的过程称为汇编。共96页6使用汇编语言编写的程序,机器不能直接识别共96页1055、汇编语言程序、汇编器和机器码程序之间的关系共96页75、汇编语言程序、汇编器和机器码程序之间的关系共96页1066、什么是伪指令
人们设计了一些专门用于指导汇编器进行汇编工作的指令,由于这些指令不形成机器码指令,它们只是在汇编器进行汇编工作的过程中起作用,所以被叫做伪指令。7、什么叫宏共96页86、什么是伪指令人们设计了一些专门用共96页107
为了提高编程效率和增强程序的可读性,有设计了一些宏。8、什么叫汇编语言程序
用汇编语言编写的程序叫做汇编语言程序。9、什么叫目标程序
自源程序翻译成的机器码程序就叫做目标程序。共96页9为了提高编程效率和增强程序的可读性共96页1085.2ARM伪指令
在ARM汇编程序语言中,有如下几种伪指令:
段定义、符号定义、数据定义、数据缓冲池定义、数据表定义、数据空间分配、汇编控制伪指令以及其他伪指令。5.2.1段定义伪指令共96页105.2ARM伪指令在ARM汇编程序语共96页109
段定义伪指令的格式为:AREA<sectionname>{<attr>},{,<attr>},…
Sectionname:段名,若段名以数字开头,则必须用符号“|”扩起来,如|1_test|。
attr:属性字段,多个属性字段用逗号分隔。共96页11段定义伪指令的格式为:Sectionn共96页110属性含义备注CODE代码段默认读/写属性为READONLYDATA数据段默认属性为READWRITEREADONLY本段为只读READWRITE本段为可读可写ALIGN表达式多源文件共享段ELF的代码段和数据段为字对齐COMMON多源文件共享段共96页12属性含义备注CODE代码段默认读/写属性为REA共96页111
AREAInit,CODE,READONLY
…………;程序段
该伪指令定义了一个代码段,段名为Init,属性为只读。
一个汇编语言程序至少要有一个段。5.2.2符号定义伪指令
符号的命名由编程者决定,但必须遵循以下约定:共96页13AREAInit,CODE,READO共96页112(1)符号区分大小写,同名的大、小写符号会被编译器认为是两个不同的符号。(2)符号在其作用范围内必须唯一。(3)自定义的符号不能与系统保留字相同。(4)符号不应与指令或伪指令同名1、定义全局变量伪指令GBLA、GBLL和GBLS共96页14(1)符号区分大小写,同名的大、小写符号会被编译共96页113GBLA、GBLL和GBLS伪指令用于定义一个ARM程序中的全局变量,并将其初始化。GBLA(GBLL和GBLS)<varible>
varible为变量名称。GBLA定义一个全局数字变量,其默认初值为0。共96页15GBLA、GBLL和GBLS伪指令用于定共96页114GBLL定义一个全局逻辑变量,其默认初值为F(假)。GBLS定义一个全局字符串变量,其默认初值为空。GBLATest1;定义一个全局数字变量,变量名为Test1GBLLTest2;定义一个全局逻辑变量,变量名为Test2共96页16GBLL定义一个全局逻辑变量,其默认初值为F(假共96页115GBLSTest1;定义一个全局字符串变量,变量名为Test3
全局变量的变量名在整个程序范围内必须具有唯一性。2、定义局部变量位指令LCLA、LCLL和LCLSLCLA、LCLL和LCLS伪指令用于定义一个ARM程序中的局部变量,并将其初始化。共96页17GBLSTest1;定义一个全局字符串变共96页116LCLA(LCLL和LCLS)<varible>
varible为变量名称。LCLA定义一个局部数字变量,其默认初值为0。LCLL定义一个局部逻辑变量,其默认初值为F(假)。LCLS定义一个局部字符串变量,其默认初值为空。共96页18LCLA(LCLL和LCLS)<varible共96页117LCLATest4;定义一个局部数字变量,变量名为Test4LCLLTest5;定义一个局部逻辑变量,变量名为Test5LCLSTest6;定义一个局部字符串变量,变量名为Test6
局部变量的变量名在变量作用范围内必须具有唯一性。共96页19LCLATest4;定义一个局部数字变量共96页118
在默认情况下,局部变量只在定义该变量的程序段内有效。3、变量赋值伪指令SETA、SETL和SETS
伪指令SETA、SETL和SETS用于给一个已经定义的全局变量或局部变量进行赋值。Test1SETA0xAA;将Test1变量赋值为0xAA。共96页20在默认情况下,局部变量只在定义该变共96页119Test2SETL{TRUE};将Test2变量赋值为真。Test3SETS“Testing”;将Test3变量赋值为“Testing”
。Test4SETA0xBB;将Test4变量赋值为0xBB。Test5SETL{TRUE};将Test5变量赋值为真。共96页21Test2SETL{TRUE};将T共96页120Test6SETS“Testing”;将Test6变量赋值为“Testing”
。4、定义寄存器列表伪指令RLIST
指令LDM/STM需要使用一个比较长的寄存器列表,使用伪指令RLIST可对一个列表定义一个统一的名称。
<name>RLIST<{list}>
name为表名成;{list}为寄存器列表。共96页22Test6SETS“Testing”;共96页121
RegListRLIST{R0-R5,R8,R10};将寄存器列表名称定义为RegList。
列表中的寄存器访问次序根据寄存器的编号由低到高,而与列表中的寄存器陪列次序无关。5.2.3程序中的标号
在汇编语言中用来表示地址的符号就叫做标号。共96页23RegListRLIST{R0-R5,R8共96页122
LDRR0,#0x3FF5000target1LDRR1,0xFFSTRR1,[R0]LDRR0,#0x3FF5008LDRR1,0x01STRR1,[R0]Btarget1;转移到target1位置上运行共96页24共96页123
这里的target1就是标号。
在ARM汇编中,根据用途不同标号主要有以下2种:(1)目标地址标号
写在一条指令前面的标号。(2)数据或数据区首地址标号
写在数据或数据区定义伪指令前面的标号。共96页25这里的target1就是标号。共96页1245.2.4数据定义伪指令
该指令的功能就是为指定的数据分配存储单元,以及用该数据对已分配存储单元进行初始化。1、DCBDCB伪指令用于分配一片连续的以字节为单位的存储区域,并用指定的表达式对其进行初始化。共96页265.2.4数据定义伪指令该指令共96页125
{<label>}DCB<expr>label为标号,为存储区域的首地址(可选)。expr为表达式,为从标号开始存放的数据。该表达式可以为0~255的数字或字符串。
Dat1DCB0x7EDCB也可用“=”代替,即Dat1=0x7E共96页27{<label>}DCB<expr>共96页1262、DCW(或DCWU)DCW(或DCWU)伪指令用于为数据分配一片连续的半字存储单元,并用表达式对其进行初始化。<label>DCW(或DCWU)<expr>
用DCW分配的字存储单元是严格按半字对齐的,而用DCWU分配的字存储单元并不严格按半字对齐。共96页282、DCW(或DCWU)DCW(或DCW共96页1273、DCD(或DCDU)DCD(或DCDU)伪指令用于分配一片连续的字存储单元,并用伪指令中指定的表达式初始化。
DataTestDCW1,2,3;分配一片连续的半字存储单元并初始化
<label>DCD(或DCDU)<expr>共96页293、DCD(或DCDU)DCD(或DCD共96页128
用DCD分配的字存储单元是字对齐的,而用DCDU分配的字存储单元并不严格要求字对齐。
DataTestDCD4,5,6;分配一片连续的存储单元并初始化DCD也可用“&”代替。4、DCFD(或DCFDU)共96页30用DCD分配的字存储单元是字对齐的,而用共96页129DCFD(或DCFDU)伪指令用于为双精度的浮点数分配一片连续的字存储单元,并用伪指令中指定的表达式初始化。每个双精度的浮点数占据两个字单元。<label>DCFD(或DCFDU)<expr>
用DCFD分配的字存储单元是字对齐的而用DCFDU分配的字存储单元并不严格字对齐。共96页31DCFD(或DCFDU)伪指令用于为双精共96页130
FDataTestDCFD2E115,-5E7;分配一片连续的字存储单元,并初始化为指定的双精度数。5、DCFS(或DCFSU)DCFS(或DCFSU)伪指令用于为单精度的浮点数分配一片连续的字存储单元,并用伪指令中指定的表达式初始化。每个单精度浮点熟占据一个字单元。共96页32FDataTestDCFD2E115,-5共96页131<label>DCFS(或DCFSU)<expr>
用DCFS分配的字存储单元是字对齐的而用DCFSU分配的字存储单元并不严格字对齐。
FDataTestDCFS2E5,-5E-7;分配一片连续的字存储单元,并初始化为指定的单精度数。6、DCQ(或DCQU)共96页33<label>DCFS(或DCFSU)<共96页132DCQ(或DCQU)伪指令用于分配一片以8字节为单位的连续存储区域,并用伪指令中指定的表达式初始化。<label>DCQ(或DCQU)<expr>
用DCQ分配的存储单元是字对齐的,而用DCQU分配的字存储单元并不严格字对齐。共96页34DCQ(或DCQU)伪指令用于分配一片以共96页133
DataTestDCQ100;分配一片连续的存储单元并初始化为指定的值。7、SPACESPACE伪指令用于分配一片连续的存储区域并初始化为0。<label>SPACE<expr>
表达式为要分配的字节数,SPACE也可用“%”代替。共96页35DataTestDCQ100;分配一片共96页134
DataSpaceSPACE100;分配连续的100字节的存储单元并初始化为0。8、LTORG
伪指令LTORG用来说明某个存储区域为一个用来暂存数据的数据缓冲区,也叫文字迟或数据缓冲池。大的代码段也可以使用多个数据缓冲池。共96页36DataSpaceSPACE100;分共96页135
AREAexample,CODE,READONLYStartBLFunc1
…Func1LDRR1,#0x800MOVPC,LRLTORG;定义数据缓冲池的开始位置
DateSPACE40;数据缓冲池有40个被初
END;始化为0的字节9、MAP和FIELD共96页37共96页136
在应用程序中经常使用一种如图所示的表:共96页38在应用程序中经常使用一种如图所示共96页137MAP可以用“^”代替。MAP用于定义一个结构化的内存表的首地址。语法格式如下:
MAP<expr>{,<baseregister>}
expr为结构化表首地址。可以为标号或数字表达式。
baseregister为基址寄存器(可选项)。基址寄存器的值与expr的值之和就是表首地址。共96页39MAP可以用“^”代替。MAP用共96页138MAPfun;fun就是内存表的首地址MAP0x100,R9;内存表的首地址为R9+0X100MAP通常和FIELD伪指令相配合来定义一个结构化的内存表。FIELD伪指令用于定义一个结构化内存表中的数据域。<label>FIELD<expr>
label为标号。共96页40MAPfun;fun就是内存表的首地址共96页139
expr为表达式。它的值为数据域所占的字节数。FIELD伪指令与MAP伪指令配合使用来定义结构化的内存表。MAP伪指令定义内存表的首地址;FIELD伪指令定义内存表中各个数据域,并可以为每个数据域指定一个标号供其他指令引用。共96页41expr为表达式。它的值为数据域所占的字节数。共96页140
MAP0X100;定义结构化内存表首地址为0X100AFIELD16;定义A的长度为16字节,位置为0X100BFIELD32;定义B的长度为32字节,位置为0X110SFIELD256;定义S的长度为256字节,位置为0X130
注意:MAP和FIELD伪指令仅用于定义数据结构,并不实际分配存储单元。FIELD也可用“#”代替。5.2.5汇编控制伪指令共96页42MAP0X100;定义结构化内存表首地共96页1411、IF、ELSE和EDNIFIF、ELSE和ENDIF伪指令能根据条件的成立与否决定是否执行某个程序段。IF逻辑表达式程序段1ELSE
程序段2ENDIF共96页431、IF、ELSE和EDNIFIF、EL共96页142IF、ELSE、ENDIF伪指令可以嵌套使用。
GBLLTest;声明一个全局逻辑变量Test
….IFTest=TRUE
程序段1ELSE
程序段2ENDIF2、WHILE和WEND共96页44IF、ELSE、ENDIF伪指令可以嵌套使用。共96页143WHILE和WEND伪指令根据条件的成立与否决定是否重复汇编一个程序段。WHILE逻辑表达式程序段WEND
若WHILE后面的逻辑表达式为真,则重复汇编该程序段,直到逻辑表达式为假。共96页45WHILE和WEND伪指令根据条件的成立共96页144WHILE和WEND伪指令可以嵌套使用。GBLACounter;声明一个全局数字变量CounterCounterSETA3;赋值
…..WHILECounter<10
程序段
WEND5.2.6其它常用的伪指令共96页46WHILE和WEND伪指令可以嵌套使用。共96页1451、定义对齐方式伪指令ALIGN
使用ALIGN伪指令可用添加填充字节的方式,使当前位置实现某种对齐方式。ALIGN{表达式{,偏移量}}
对齐方式为2表达式的值。偏移量为一个数字表达式,若使用该字段,则当前位置的对齐方式为2表达式的值+偏移量。共96页471、定义对齐方式伪指令ALIGN使用AL共96页146
;指定后面的指令为8字节对齐
AREAInit,CODE,READONLY,ALIGN=3
代码段
END2、CODE16和CODE32
CODE16用来表明其后的指令均为16位Thumb指令;CODE32伪指令则表明其后面的指令均为32位ARM指令。共96页48;指定后面的指令为8字节对齐2、CODE16和共96页147
CODE16(或CODE32)
AREAInit,CODE,READONLY
…..CODE32LDRR0,#NEXT+1BXR0
…CODE16NEXTLDRR3,#0X3FF
…END共96页49CODE16(或CODE32)AREAIn共96页1483、定义程序入口点伪指令ENTRYENTRY伪指令用于指定汇编程序的入口点。
ENTRY
AREAInit,CODE,READONLYENTRY;
…..共96页503、定义程序入口点伪指令ENTRYENT共96页1494、汇编结束伪指令ENDEND伪指令用于通知编译器汇编工作到此结束,不再往下汇编了。
END
AREAInit,CODE,READONLY
…END共96页514、汇编结束伪指令ENDEND伪指令用于共96页1505、等效伪指令EQUEQU伪指令用于为程序中的常量、标号等定义一个等效的字符名字,其作用类似于C语言中的#define。
名称EQU表达式{,类型}EQU也可用“*”代替。共96页525、等效伪指令EQUEQU伪指令用于为程共96页151
由EQU伪指令定义的字符名称,当其表达式为32位常量时,可以指定表达式的数据类型,有以下三种类型:CODE16、CODE32和DATA。
TestEQU50;定义标号Test的值为50AddrEQU0x55,CODE32;定义Addr的值为0x55,其该处为32位的ARM指令共96页53由EQU伪指令定义的字符名称,当其表达式共96页1526、外部可引用符号声明伪指令EXPORT(或GLOBAL)
用伪指令EXPORT可以声明一个其他源文件可引用的符号,这种符号也叫做外部可引用符号。EXPORT符号{[WEAK]}EXPORT可用GLOBAL代替。共96页546、外部可引用符号声明伪指令EXPORT(或GL共96页153
标号在程序中区分大小写,[WEAK]选项声明其他的同名标号优先于该标号被引用。
AREAInit,CODE,READONLYEXPORTStest
…END7、IMPORT共96页55标号在程序中区分大小写,[WEAK]选项共96页154
当在一个源文件中需要使用另外
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 美发行业投标流程管理
- 保安人员解除聘用合同申请
- 房地产投资合同执行细则
- 广告行业发票处理:发票管理办法
- 排水设施维修服务合同
- 环保工程模板施工劳务合同
- 智能家居系统招投标公证函
- 培训养老机构防疫措施
- 临时市场推广员招聘书
- 投诉管理知识库更新指南
- 第五讲铸牢中华民族共同体意识-2024年形势与政策
- 【寒假阅读提升】四年级下册语文试题-非连续性文本阅读(一)-人教部编版(含答案解析)
- 霍去病课件教学课件
- 邮政储蓄银行的2024年度借款合同范本
- 山东省滨州市博兴县2024-2025学年九年级上学期11月期中数学试题
- 2.1 充分发挥市场在资源配置中的决定性作用(课件) 2024-2025学年高中政治 必修2 经济与社会
- 外立面改造项目脚手架施工专项方案
- ASTMD638-03中文版塑料拉伸性能测定方法
- 统编版(2024新版)七年级上册道德与法治期中模拟试卷(含答案)
- 砌筑实训课程设计
- 译林版(2024新版)七年级上册英语期中复习:完型及阅读 练习题汇编(含答案)
评论
0/150
提交评论