1TM第6章ARM汇编伪指令与伪操作2、伪操作:为完成汇编程序做各种准备工作,只在汇编过程中起作用,一旦汇编结束,它的作用也随之结束。3、宏指令:是一段独立的程序代码,可插在源程序中。与子程序相似,但有本质不同。1、伪指令:在汇编时将被合适的指令代替。伪操作、宏指令一般与编译器有关,常用ARM编译开发环境有2种:GNU(基于EmbestIDE环境)和ADS(ARM公司提供)2TM2目前常用的编译环境有2种:1.ADS/SDT、RealViewMDK等ARM公司推出的开发工具2.GNUARM开发工具3TM31.ADS/SDT、RealViewMDK等ARM公司推出的开发工具ADS由ARM公司推出,使用了CodeWarrior公司的编译器。针对ARM资源配置为用户提供了在CodeWarriorIDE集成环境下配置各种ARM开发工具的能力。以ARM为目标平台的工程创建向导,可以使用户以此为基础,快速创建ARM和Thumb工程。4TM4ARM将Keil公司收购之后,正式推出了针对ARM微控制器的开发工具RealViewMicrocontrollerDevelopmentKit(简称RealViewMDK或者MDK),它将ARM开发工具RealViewDevelopmentSuite(简称RVDS)的编译器RVCT与Keil的工程管理、调试仿真工具集成在一起,是一款非常强大的ARM微控制器开发工具。5TM52.GNUARM开发工具GNU是“GNU‘sNotUnix”的递归缩写。在1983年9月27日由RichardStallman公开发起GNU计划,它的目标是创建一套完全自由的操作系统。GNU格式ARM汇编语言程序主要是面对在ARM平台上移植嵌入式Linux操作系统,GNU组织开发的基于ARM平台的编译工具有主要由GNU的汇编器as,交叉汇编器gcc和连接器ld组成。6TM66.1汇编语言伪指令伪指令是ARM处理器支持的汇编语言程序里的特殊助记符,它不在处理器运行期间由机器执行,只是在汇编时将被合适的机器指令代替成ARM或Thumb指令,从而实现真正的指令操作。ARM伪指令有四条,分别为ADR伪指令、ADRL伪指令、LDR伪指令、NOP伪指令。7TM7ARM伪指令——大范围的地址读取LDR伪指令用于加载32位的立即数或一个地址值到指定寄存器。在汇编编译源程序时,LDR伪指令被编译器替换成一条合适的指令。若加载的常数未超出MOV或MVN的范围,则使用MOV或MVN指令代替该LDR伪指令,否则汇编器将常量放入文字池,并使用一条程序相对偏移的LDR指令从文字池读出常量。LDR{cond}register,=expr|label_exprLDR伪指令格式指令执行的条件码加载的目标寄存器基于PC的地址表达式或外部表达式注意:1.从指令位置到文字池的偏移量必须小于4KB;2.与ARM指令的LDR相比,伪指令的LDR的参数有“=”号。8TM8ARM伪指令——大范围的地址读取LDR伪指令用于加载32位的立即数或一个地址值到指定寄存器。在汇编编译源程序时,LDR伪指令被编译器替换成一条合适的指令。若加载的常数未超出MOV或MVN的范围,则使用MOV或MVN指令代替该LDR伪指令,否则汇编器将常量放入文字池,并使用一条程序相对偏移的LDR指令从文字池读出常量。应用示例(加载常量):LDRR2,=0xFF0;MOVR2,#0xFF0LDRR0,=0xFF000000;MOVR0,#0xFF000000LDRR1,=0xFFFFFFFE;MVNR1,#0x19TM9ARM伪指令——大范围的地址读取LDR伪指令用于加载32位的立即数或一个地址值到指定寄存器。在汇编编译源程序时,LDR伪指令被编译器替换成一条合适的指令。若加载的常数未超出MOV或MVN的范围,则使用MOV或MVN指令代替该LDR伪指令,否则汇编器将常量放入文字池,并使用一条程序相对偏移的LDR指令从文字池读出常量。应用示例(加载地址):...LDRR1,=InitStack...InitStackMOVR0,LR...使用伪指令将程序标号InitStack的地址存入R110TM10ARM伪指令——大范围的地址读取LDR伪指令用于加载32位的立即数或一个地址值到指定寄存器。在汇编编译源程序时,LDR伪指令被编译器替换成一条合适的指令。若加载的常数未超出MOV或MVN的范围,则使用MOV或MVN指令代替该LDR伪指令,否则汇编器将常量放入文字池,并使用一条程序相对偏移的LDR指令从文字池读出常量。应用示例(加载地址):编译后的反汇编代码:...LDRR1,=InitStack...InitStackMOVR0,LR......0x60LDRR1,0xb4...0x64MOVR0,LR...0xb4DCD0x64使用伪指令将程序标号InitStack的地址存入R1地址程序代码11TM11ARM伪指令——大范围的地址读取LDR伪指令用于加载32位的立即数或一个地址值到指定寄存器。在汇编编译源程序时,LDR伪指令被编译器替换成一条合适的指令。若加载的常数未超出MOV或MVN的范围,则使用MOV或MVN指令代替该LDR伪指令,否则汇编器将常量放入文字池,并使用一条程序相对偏移的LDR指令从文字池读出常量。应用示例(加载地址):编译后的反汇编代码:...LDRR1,=InitStack...InitStackMOVR0,LR......0x60LDRR1,0xb4...0x64MOVR0,LR...0xb4DCD0x64使用伪指令将程序标号InitStack的地址存入R1LDR伪指令被汇编成一条LDR指令,并在文字池中定义了一个常量,该常量为InitStack标号的地址12TM12ARM伪指令——中等范围的地址读取ADRL伪指令将基于PC相对偏移的地址值或基于寄存器相对偏移的地址值读取到寄存器中,比ADR伪指令可以读取更大范围的地址。在汇编编译器编译源程序时,ADRL伪指令被编译器替换成两条合适的指令。若不能用两条指令实现,则产生错误,编译失败。ADRL{cond}register,exprADRL伪指令格式指令执行的条件码加载的目标寄存器地址表达式地址表达式expr的取指范围:当地址值是字节对齐时,其取指范围为-64K~64K;当地址值是字对齐时,其取指范围为-256K~256K;13TM13ARM伪指令——中等范围的地址读取ADRL伪指令将基于PC相对偏移的地址值或基于寄存器相对偏移的地址值读取到寄存器中,比ADR伪指令可以读取更大范围的地址。在汇编编译器编译源程序时,ADRL伪指令被编译器替换成两条合适的指令。若不能用两条指令实现,则产生错误,编译失败。...ADRLR0,Delay...DelayMOVR0,r14...应用示例(源程序):使用伪指令将程序标号Delay的地址存入R014TM14ARM伪指令——中等范围的地址读取ADRL伪指令将基于PC相对偏移的地址值或基于寄存器相对偏移的地址值读取到寄存器中,比ADR伪指令可以读取更大范围的地址。在汇编编译器编译源程序时,ADRL伪指令被编译器替换成两条合适的指令。若不能用两条指令实现,则产生错误,编译失败。...ADRLR0,Delay...DelayMOVR0,r14...应用示例(源程序):...0x20ADDr1,pc,#400x24ADDr1,r1,#FF00...0xFF68MOVr0,r14...编译后的反汇编代码:使用伪指令将程序标号Delay的地址存入R0地址程序代码15TM15ARM伪指令——中等范围的地址读取ADRL伪指令将基于PC相对偏移的地址值或基于寄存器相对偏移的地址值读取到寄存器中,比ADR伪指令可以读取更大范围的地址。在汇编编译器编译源程序时,ADRL伪指令被编译器替换成两条合适的指令。若不能用两条指令实现,则产生错误,编译失败。...ADRLR0,Delay...DelayMOVR0,r14...应用示例(源程序):...0x20ADDr1,pc,#400x24ADDr1,r1,#FF00...0xFF68MOVr0,r14...编译后的反汇编代码:使用伪指令将程序标号Delay的地址存入R0ADRL伪指令被汇编成两条指令16TM16ARM伪指令——小范围的地址读取ADR伪指令将基于PC相对偏移的地址值或基于寄存器相对偏移的地址值读取到寄存器中。在汇编编译器编译源程序时,ADR伪指令被编译器替换成一条合适的指令。通常,编译器用一条ADD指令或SUB指令来实现该ADR伪指令的功能,若不能用一条指令实现,则产生错误,编译失败。ADR{cond}register,exprADR伪指令格式指令执行的条件码加载的目标寄存器地址表达式地址表达式expr的取指范围:当地址值是字节对齐时,其取指范围为-255~255;当地址值是字对齐时,其取指范围为-1020~1020;17TM17ARM伪指令——小范围的地址读取ADR伪指令将基于PC相对偏移的地址值或基于寄存器相对偏移的地址值读取到寄存器中。在汇编编译器编译源程序时,ADR伪指令被编译器替换成一条合适的指令。通常,编译器用一条ADD指令或SUB指令来实现该ADR伪指令的功能,若不能用一条指令实现,则产生错误,编译失败。...ADRR0,Delay...DelayMOVR0,r14...应用示例(源程序):使用伪指令将程序标号Delay的地址存入R018TM18...0x20ADDr1,pc,#0x3c......0x64MOVr0,r14...ARM伪指令——小范围的地址读取ADR伪指令将基于PC相对偏移的地址值或基于寄存器相对偏移的地址值读取到寄存器中。在汇编编译器编译源程序时,ADR伪指令被编译器替换成一条合适的指令。通常,编译器用一条ADD指令或SUB指令来实现该ADR伪指令的功能,若不能用一条指令实现,则产生错误,编译失败。...ADRR1,Delay...DelayMOVR0,r14...应用示例(源程序):编译后的反汇编代码:使用伪指令将程序标号Delay的地址存入R0地址程序代码19TM19ARM伪指令——小范围的地址读取ADR伪指令将基于PC相对偏移的地址值或基于寄存器相对偏移的地址值读取到寄存器中。在汇编编译器编译源程序时,ADR伪指令被编译器替换成一条合适的指令。通常,编译器用一条ADD指令或SUB指令来实现该ADR伪指令的功能,若不能用一条指令实现,则产生错误,编译失败。...ADRR0,Delay...DelayMOVR0,r14...应用示例(源程序):...0x20ADDr1,pc,#0x3c......0x64MOVr0,r14...编译后的反汇编代码:使用伪指令将程序标号Delay的地址存入R0ADR伪指令被汇编成一条指令20TM20ARM伪指令——小范围的地址读取ADR伪指令将基于PC相对偏移的地址值或基于寄存器相对偏移的地址值读取到寄存器中。在汇编编译器编译源程序时,ADR伪指令被编译器替换成一条合适的指令。通常,编译器用一条ADD指令或SUB指令来实现该ADR伪指令的功能,若不能用一条指令实现,则产生错误,编译失败。应用示例2(查表):ADRR0,DISP_TAB;加载转换表地址LDRBR1,[R0,R2];使用R2作为参数,进行查表…DISP_TABDCB0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF821TM21ARM伪指令——空操作伪指令NOP伪指令在汇编时将会被代替成ARM中的空操作,比如可能是“MOVR0,R0”指令等。NOP可用于延时操作。NOPNOP伪指令格式应用示例(延时子程序):movR1,#0x1234DelayNOP;空操作NOPNOPSUBSR1,R1,#1;循环次数减一BNEDelay;如果循环没有结束,跳转Delay继续MOVPC,LR;子程序返回22TM226.2ARM汇编语言伪操作伪操作(Directive)是ARM汇编语言程序里的一些特