主要内容•汇编语言程序的格式汇编程序语句的行格式;预定义寄存器与内建常量;ARM伪指令ARM伪操作(指示符)•ARM汇编语言编程举例1、两种常见的ARM编译开发环境ADS/SDTIDE开发环境:它由ARM公司开发,使用了CodeWarrior公司的编译器集成了GNU开发工具的IDE开发环境::它由GNU的汇编器as、交叉编译器gcc、和链接器ld等组成。ARM汇编程序语法格式•简单的ARM程序-ADS;文件名:TEST1.S;功能:实现两个寄存器相加;说明:使用ARMulate软件仿真调试AREAExample1,CODE,READONLY;声明代码段Example1ENTRY;标识程序入口CODE32;声明32位ARM指令STARTMOVR0,#0;设置参数MOVR1,#10LOOPBLADD_SUB;调用子程序ADD_SUBBLOOP;跳转到LOOPADD_SUBADDSR0,R0,R1;R0=R0+R1MOVPC,LR;子程序返回END;文件结束使用“;”进行注释标号顶格写实际代码段声明文件结束#文件名:TEST1.S#功能:实现两个寄存器相加#说明:.text.arm/*声明32位ARM指令*/_start:MOVR0,#0/*设置参数*/MOVR1,#10LOOP:BLADD_SUB/*调用子程序ADD_SUB*/BLOOP/*跳转到LOOP*/ADD_SUB:ADDSR0,R0,R1/*R0=R0+R1*/MOVPC,LR/*子程序返回*/.end/*文件结束*/GNU编译环境ARM汇编程序语法格式(1)预定义的寄存器R0-R15或者r0-r15、sp、LR、PC等(2)内建变量{TRUE}{FALSE}PCor.当前指令的地址;{ENDIAN}如果汇编器在大端方式,值为big,否则值为little;{CODESIZE}如果正在汇编Thumb代码,值为16,否则值为32;ARM汇编语句格式——ADS汇编器ARM汇编语句的格式如下:{symbol}{instruction|directive|pseudo-instruction}{;comment}说明:(1)symbol:符号。在ARM汇编语言中,符号在指令和伪指令中用作地址标号,在一些伪操作中用作变量或常量。符号的使用有以下一些规则:①符号必须从一行的行头开始。②符号由大小写字母、数字以及下划线组成,但不能包含空格。③符号区分大小写。——ADS汇编器④局部标号以数字开头,其他符号都不能以数字开头。⑤符号在作用范围内是唯一的,即在其作用范围内不能有同名的符号。⑥程序中的符号不能与系统的内部变量或系统预定义的符号同名。⑦程序中的符号通常不要与指令助记符或伪操作同名。——ADS汇编器(2)instruction:指令。在ARM汇编语言中,指令不能从一行的行头开始。在一行语句中,指令的前面必须有空格或符号。(3)directive:伪操作。(4)pseudo-instruction:伪指令。(5)comment:语句的注释。在ARM汇编语言中,注释以分号“;”开头。注释的结尾即为一行的结尾。注释也可单独占用一行。——ADS汇编器关于ARM汇编语句,需要说明的有以下几点:(1)指令、伪指令以及伪操作的助记符可全部使用大写字母,也可全部使用小写字母,但不能在一个助记符中既有大写字母又有小写字母。(2)在程序中,语句之间最好适当地插入空行,这样可提高源代码的可读性。(3)如果一条语句很长,为提高可读性,可使用“\”将其分成若干行进行书写。在“\”后面不能再有其他字符,包括空格和制表符。——ADS汇编器——ADS汇编器返回symbols——ADS汇编器ARM伪指令不属于ARM指令集中的指令,是为了编程方便而定义的。伪指令可以像其它ARM指令一样使用,但在编译时这些指令将被等效的ARM指令代替。ARM伪指令有四条,分别为ADR伪指令、ADRL伪指令、LDR伪指令、NOP伪指令。ARM汇编语言的伪指令伪指令语法格式作用ADRADR{cond}register,expr将基于PC或基于寄存器的地址值读取到寄存器中。小范围的地址读取。ADRLADRL{cond}register,expr将基于PC或基于寄存器的地址值读取到寄存器中。中等范围的地址读取。LDRLDR{cond}register,=[expr|label-expr]将一个32位的立即数或者一个地址值读取到寄存器中。大范围的地址读取。NOPNOP在汇编时将被替换成ARM中的空操作。•ARM伪指令——小范围的地址读取ADR伪指令将基于PC相对偏移的地址值或基于寄存器相对偏移的地址值读取到寄存器中。在汇编编译器编译源程序时,ADR伪指令被编译器替换成一条合适的指令。通常,编译器用一条ADD指令或SUB指令来实现该ADR伪指令的功能,若不能用一条指令实现,则产生错误,编译失败。ADR{cond}register,exprADR伪指令格式指令执行的条件码加载的目标寄存器地址表达式地址表达式expr的取指范围:当地址值不是字对齐时,其取指范围为-255~255;当地址值是字对齐时,其取指范围为-1020~1020;当地址值是16字节对齐时,其取指范围将更大。•ARM伪指令——小范围的地址读取ADR伪指令将基于PC相对偏移的地址值或基于寄存器相对偏移的地址值读取到寄存器中。在汇编编译器编译源程序时,ADR伪指令被编译器替换成一条合适的指令。通常,编译器用一条ADD指令或SUB指令来实现该ADR伪指令的功能,若不能用一条指令实现,则产生错误,编译失败。...ADRR0,Delay...DelayMOVR0,r14...应用示例(源程序):使用伪指令将程序标号Delay的地址存入R0...0x20ADDr0,pc,#0x3c......0x64MOVr0,r14...•ARM伪指令——小范围的地址读取ADR伪指令将基于PC相对偏移的地址值或基于寄存器相对偏移的地址值读取到寄存器中。在汇编编译器编译源程序时,ADR伪指令被编译器替换成一条合适的指令。通常,编译器用一条ADD指令或SUB指令来实现该ADR伪指令的功能,若不能用一条指令实现,则产生错误,编译失败。...ADRR0,Delay...DelayMOVR0,r14...应用示例(源程序):编译后的反汇编代码:使用伪指令将程序标号Delay的地址存入R0地址程序代码•ARM伪指令——小范围的地址读取ADR伪指令将基于PC相对偏移的地址值或基于寄存器相对偏移的地址值读取到寄存器中。在汇编编译器编译源程序时,ADR伪指令被编译器替换成一条合适的指令。通常,编译器用一条ADD指令或SUB指令来实现该ADR伪指令的功能,若不能用一条指令实现,则产生错误,编译失败。...ADRR0,Delay...DelayMOVR0,r14...应用示例(源程序):...0x20ADDr0,pc,#0x3c......0x64MOVr0,r14...编译后的反汇编代码:使用伪指令将程序标号Delay的地址存入R0ADR伪指令被汇编成一条指令•ARM伪指令——小范围的地址读取ADR伪指令将基于PC相对偏移的地址值或基于寄存器相对偏移的地址值读取到寄存器中。在汇编编译器编译源程序时,ADR伪指令被编译器替换成一条合适的指令。通常,编译器用一条ADD指令或SUB指令来实现该ADR伪指令的功能,若不能用一条指令实现,则产生错误,编译失败。应用示例2(查表):ADRR0,DISP_TAB;加载转换表地址LDRBR1,[R0,R2];使用R2作为参数,进行查表…DISP_TABDCB0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8•ARM伪指令——中等范围的地址读取ADRL伪指令将基于PC相对偏移的地址值或基于寄存器相对偏移的地址值读取到寄存器中,比ADR伪指令可以读取更大范围的地址。在汇编编译器编译源程序时,ADRL伪指令被编译器替换成两条合适的指令。若不能用两条指令实现,则产生错误,编译失败。ADRL{cond}register,exprADRL伪指令格式指令执行的条件码加载的目标寄存器地址表达式地址表达式expr的取指范围:当地址值不是字对齐时,其取指范围为-64K~64K;当地址值是字对齐时,其取指范围为-256K~256K;当地址值是16字节对齐时,其取指范围将更大。•ARM伪指令——中等范围的地址读取ADRL伪指令将基于PC相对偏移的地址值或基于寄存器相对偏移的地址值读取到寄存器中,比ADR伪指令可以读取更大范围的地址。在汇编编译器编译源程序时,ADRL伪指令被编译器替换成两条合适的指令。若不能用两条指令实现,则产生错误,编译失败。...ADRLR0,Delay...DelayMOVR0,r14...应用示例(源程序):使用伪指令将程序标号Delay的地址存入R0•ARM伪指令——中等范围的地址读取ADRL伪指令将基于PC相对偏移的地址值或基于寄存器相对偏移的地址值读取到寄存器中,比ADR伪指令可以读取更大范围的地址。在汇编编译器编译源程序时,ADRL伪指令被编译器替换成两条合适的指令。若不能用两条指令实现,则产生错误,编译失败。...ADRLR0,Delay...DelayMOVR0,r14...应用示例(源程序):...0x20ADDr0,pc,#400x24ADDr0,r0,#0...0x68MOVr0,r14...编译后的反汇编代码:使用伪指令将程序标号Delay的地址存入R0地址程序代码•ARM伪指令——中等范围的地址读取ADRL伪指令将基于PC相对偏移的地址值或基于寄存器相对偏移的地址值读取到寄存器中,比ADR伪指令可以读取更大范围的地址。在汇编编译器编译源程序时,ADRL伪指令被编译器替换成两条合适的指令。若不能用两条指令实现,则产生错误,编译失败。...ADRLR0,Delay...DelayMOVR0,r14...应用示例(源程序):...0x20ADDr0,pc,#400x24ADDr0,r0,#0...0x68MOVr0,r14...编译后的反汇编代码:使用伪指令将程序标号Delay的地址存入R0ADRL伪指令被汇编成两条指令,尽管第2条指令并没有意义•ARM伪指令——大范围的地址读取LDR伪指令用于加载32位的立即数或一个地址值到指定寄存器。在汇编编译源程序时,LDR伪指令被编译器替换成一条合适的指令。若加载的常数未超出MOV或MVN的范围,则使用MOV或MVN指令代替该LDR伪指令,否则汇编器将常量放入文字池,并使用一条程序相对偏移的LDR指令从文字池读出常量。LDR{cond}register,=exprLDR伪指令格式指令执行的条件码加载的目标寄存器基于PC的地址表达式或外部表达式•ARM伪指令——大范围的地址读取LDR伪指令用于加载32位的立即数或一个地址值到指定寄存器。在汇编编译源程序时,LDR伪指令被编译器替换成一条合适的指令。若加载的常数未超出MOV或MVN的范围,则使用MOV或MVN指令代替该LDR伪指令,否则汇编器将常量放入文字池,并使用一条程序相对偏移的LDR指令从文字池读出常量。应用示例(源程序):...LDRR1,=InitStack...InitStackMOVR0,LR...使用伪指令将程序标号InitStack的地址存入R1•ARM伪指令——大范围的地址读取LDR伪指令用于加载32位的立即数或一个地址值到指定寄存器。在汇编编译源程序时,LDR伪指令被编译器替换成一条合适的指令。若加载的常数未超出MOV或MVN的范围,则使用MOV或MVN指令代替该LDR伪指令,否则汇编器将常量放入文字池,并使用一条程序相对偏移的LDR指令从文字池读出常量。应用示例(源程序):编译后的反汇编代码:...LDRR1,=InitStack...InitStackMOVR0,LR......0x60LDRR1,0xb4...0x64MOVR0,LR...0xb4DCD0x64使用伪指令将程序标号InitStack的地址存入R