
arm汇编语言伪指令.doc
7页ARM 汇编语言伪指令ARM 中伪指令不是真正的 ARM 指令或者 Thumb 指令,这些伪指令在汇 编编译时对源程序进行汇编处理时被替换成对应的 ARM 或 Thumb 指令(序列) ARM 伪指令包括 ADR、ADRL、LDR 和 NOP 等1、ADR(小范围的地址读取伪指令)该指令将基于 PC 的地址值或基于寄存器的地址值读取到寄存器中语法格式ADR{cond} register, expr其中,cond 为可选的指令执行的条件register 为目标寄存器expr 为基于 PC 或者基于寄存器的地址表达式,其取值范围如下:当地址值不是字对齐时,其取值范围为-255~255.当地址值是字对齐时,其取值范围为-1020~1020当地址值是 16 字节对齐时,其取值范围将更大在汇编编译器处理源程序时,ADR 伪指令被编译器替换成一条合适的指令 通常,编译器用一条 ADD 指令或 SUB 指令来实现该 ADR 伪指令的功能因为 ADR 伪指令中的地址是基于 PC 或者基于寄存器的,所以 ADR 读取 到的地址为位置无关的地址当 ADR 伪指令中的地址是基于 PC 时,该地址与 ADR 伪指令必须在同一个代码段中。
示例start MOV r0,#10 ;因为 PC 值为当前指令地址值加 8 字节ADR r4, start ;本 ADR 伪指令将被编译器替换成 SUB r4,pc,#0xc2、 ADRL(中等范围的地址读取伪指令)该指令将基于 PC 或基于寄存器的地址值读取到寄存器中ADRL 伪指令 比 ADR 伪指令可以读取更大范围的地址ADRL 伪指令在汇编时被编译器替换 成两条指令,即使一条指令可以完成该伪指令的功能语法格式ADRL{cond} register,expr示例start MOV r0,#10 ;因为 PC 值为当前指令地址值加 8 字节ADRL r4,start+60000 ;本 ADRL 伪指令将被编译器替换成下面两条指令ADD r4,pc,#0xe800ADD r4,r4,#0x2543、LDR(大范围的地址读取伪指令)LDR 伪指令将一个 32 位的常数或者一个地址值读取到寄存器中语法格式LDR{cond} register, =[expr|label-expr]其中,expr 为 32 位的常量编译器将根据 expr 的取值情况,如下处理 LDR 伪指令:当 expr 表示的地址值没有超过 MOV 或 MVN 指令中地址的取值范围时, 编译器用合适的 MOV 或 MVN 指令代替该 LDR 伪指令当 expr 表示的地址值超过了 MOV 或者 MVN 指令中地址的取值范围时, 编译器将该常数放在数据缓冲区中,同时用一条基于 PC 的 LDR 指令读取该常 数。
label-expr 为基于 PC 的地址表达式或者是外部表达式当 label-expr 为基 于 PC 的地址表达式时,编译器将 label-expr 表示的数值放在数据缓冲区 (literal pool)中,然后将该 LDR 伪指令处理成一条基于 PC 到该数据缓冲区 单元的 LDR 指令,从而将该地址值读取到寄存器中这时,要求该数据缓冲区 单元到 PC 的距离小于 4KB当 label-expr 为外部表达式,或者非当前段的表 达式时,汇编编译器将在目标文件中插入一个地址重定位伪操作,这样连接器 将在连接时生成该地址LDR 伪指令主要有以下两种用途:当需要读取到寄存器中的数据超过了 MOV 及 MVN 指令可以操作的范围时, 可以使用 LDR 伪指令将该数据读取到寄存器中将一个基于 PC 的地址值或者外部的地址值读取到寄存器中由于这种地 址值是在连接时确定的,所以这种代码不是位置无关的同时 LDR 伪指令的 PC 值到数据缓冲区中的目标数据所在的地址的偏移量要小于 4KB示例将 0xff0 读取到 R1 中LDR R1,=0xFF0汇编后将得到:MOV R1,0xFF0将 0xfff 读取到 R1 中LDR R1,=0xFFF汇编后将得到:LDR R1,[PC,OFFSET_TO_LPOOL]…LPOOL DCD 0xFFF将外部地址 ADDR1 读取到 R1 中LDR R1,=ADDR1汇编后将得到:LDR R1,[PC,OFFSET_TO_LPOOL]…LPOOL DCD ADDR14、NOP 空操作伪指令在汇编时将被替换成 ARM 中的空操作,如 MOV R0,R0NOP 伪指令不影响 CPSR 中的条件标志位ARM 汇编程序中的符号 在 ARM 汇编语言中,符号(symbols)可以代表地址(addresse)、变量 (variables)和数字常量(numeric constants)。
当符号代表地址时,又称为 标号(lable)当标号以数字开头时,其作用范围为当前段(当前段没有使用 ROUT 伪操作时),这种标号又称为局部标号(lacal lable)符号变量包括变 量、数字常量、标号和局部标号 1、变量 在程序中,变量的值在汇编处理过程中可能会发生改变在 ARM 汇编中 变量有数字变量、逻辑变量和串变量 3 种类型变量的类型在程序中是不可以 改变的 数字变量的取值范围为数字常量和数字表达式所能表示的数值;逻辑变量 的取值范围为{true}和{flash};串变量的取值范围为串表达式可以表达的范围 在 ARM 汇编语言中,使用 GBLA、GBLL 及 GBLS 声明全局变量;使用 LCLA、LCLL 及 LCLS 声明局部变量;使用 SETA、SETL 及 SETS 为这些变 量赋值2、数字常量 数字常量是 32 位的整数在 ARM 汇编语言中,使用 EQU 来定义数字常 量数字常量一经定义就不可修改 进行大小比较时,认为数字常量都是无符 号数3、汇编时变量的替换 如果在串变量前有一个$字符,在汇编时编译器将用改串的数值来取代该串 变量 对于数字变量来说,如果该变量前面有一个$字符,在汇编时编译器将该数 字变量的数值转换成十六进制的串,然后用该十六进制的串取代$字符后的数字 变量。
对于逻辑变量来说,如果该逻辑变量前面有一个$字符,在汇编时编译器将 该逻辑变量替换成它的取值(T 或者 F)如果程序中需要字符$,则用$$来表示,编译器将不进行变量替换,而是 将$$当作$.通常情况下,包含在两个竖线(|)之间的$并不表示进行变量替换但是 如果竖线(|)是在双引号内,则将进行变量替换使用“.”来表示变量名称的结束4、标号 标号是表示程序中的指令或者数据地址的符号根据标号的生成方式可分 为 3 种: 基于 PC 的标号基于 PC 的标号是位于目标指令前或者程序中数据定义 伪操作前的标号这种标号在汇编时将被处理成 PC 值加上(或减去)一个数 字常量常用于表示跳转指令的目标地址,或者代码段中所嵌入的少量数据 基于寄存器的标号基于寄存器的标号常用 MAP 和 FIELD 未定义操作, 也可以该用 EQU 伪定义这种标号在汇编时将被处理成寄存器的值加上(或 减去)一个数据常量常用于访问数据段中的数据 绝对地址绝对地址是一个 32 位数据它可以寻址 232 -1,即直接可以 寻址整个内存空间 5、局部标号 局部标号主要在局部范围内使用它由两部组成:开头是一个 0-99 直接的 数字,后面紧接一个通常表示该局部变量作用范围的符号。
局部变量的作用范围通常为当前段,也可以用伪操作 ROUT 来定义局部变 量的作用范围局部变量定义的语法格式如下:N{routname},其中,N 为 0~99 之间的数字routname 为符号,通常为 该变量作用范围的名称(用 ROUT 伪操作定义的)局部变量引用的语法格式如下:%{F|B}{A|T}N{routname}其中,N 为局部变量的数字号routname 为当前作用范围的名称(用 ROUT 伪操作定义的)%表示引用操作F 指示编译器只向前搜索B 指示编译器只向后搜索A 指示编译器搜索宏的所有嵌套层次T 指示编译器搜索宏的当前层次如果 F 和 B 都没有指定,编译器先向前搜索,再向后搜索如果 A 和 T 都没有指定,编译器搜索所有从当前层次到宏的最高层次,比 当前层次低的层次不再搜索如果指定了 routname,编译器向前搜索最近的 ROUT 伪操作,若 routname 与该 ROUT 伪操作定义的名称不匹配,编译器报告错误,汇编失败ARM 汇编语言中的表达式表达式是由符号、数值、单目或多目操作符以及括号组成的1、字符串表达式字符串表达式由字符串、字符串变量、操作符以及括号组成。
字符串的最 大长度为 512 字节,最小长度为 0.下面介绍字符串表达式的组成元素字符串:由包含在双引号内的一系列的字符组成字符串的长度受到 ARM 汇编语言语句长度的限制当在字符串中包含美元符号$或者引号"时,用$$ 表示一个$,用""表示一个"字符串变量:用伪操作 GBLS 或者 LCLS 声明,用 SETS 赋值操作符:(1)LEN:返回字符串的长度:LEN:A其中,A 为字符串变量(2)CHR:可以将 0~255 之间的整数作为含一个 ASCII 字符的字符串 当有些 ASCII 字符不方便放在字符串中时,可以使用 CHR 将其放在字符串表 达式中CHR:A其中,A 为某一字符的 ASCII 值(3)STR:将一个数字量或者逻辑表达式转换成串对于 32 位的数字量 而言,STR 将其转换成 8 个十六进制数组成的串;对于逻辑表达式而言,STR 将其转换成字符串 T 或者 F:STR:A其中,A 为数字量或者逻辑表达式(4)LEFT:返回一个字符串最左端一定长度的子串A:LEFT:B其中,A 为源字符串,B 为数字量,表示 LEFT 将返回的字符个数(5)RIGHT:返回一个字符串最右端一定长度的子串A:RIGHT:B其中,A 为源字符串,B 为数字量,表示 RIGHT 将返回的字符个数(6)CC:用于连接两个字符串。
A:CC:B其中,A 为第 1 个源字符串B 为第 2 个源字符串CC 操作符将字符串 B 连接在字符串 A 的后面2、数字表达式数字表达式由数字常量、数字变量、操作符和括号组成数字变量用伪操作 GBLA 或者 LCLA 声明,用 SETA 赋值,它代表一个 32 位的数字量操作符:(1)NOT:按位取反:NOT:A其中,A 为一个 32 位数字量(2)+、—、×、/及 MOD 算术操作符A+B,A-B,A×B,A/BA:MOD:B 表示 A 除以 B 的余数(3)ROL,ROR,SHL,SHR 移位A:ROL:B 将整数 A 循环左移 B 位A:SHL:B 将整数 A 左移 B 位(4)AND、OR 及 EOR 按位逻辑操作符A:AND:B 将数字表达式 A 和 B 按位作逻辑与操作3、基于寄存器和基于 PC 的表达式基于寄存器的表达式表示了某个寄存器的值加上(或者减去)一个数字表 达式基于 PC 的表达式表示了 PC 寄存器的值加上(或减去)一个数字表达式 基于 PC 的表达式通常由程序中的标号与一个数字表达式组成相关的操作符:(1)BASE:返回基于寄存器的表达式中的寄存器编号BASE:A A 为基于寄存器的表达式(2)INDEX:返回基于寄存器的表达式相对于其基址寄存器的偏移量。
INDEX:A A 为基于寄存器的表达式(3)+、﹣:正负号,可以放在数字表达式或者基于 PC 的表达式前面A(﹣A) A 为基于 PC 的表达式或者数字表达式4、逻辑表达式由逻辑量、逻辑操作符、关系操作符以及括号组成,取值范围为{FLASE} 和{TRUE}关系操作符:用于表示两个同类表达式之间的关系关系操作符和它的两 个操作数组成一个逻辑表达式,其取值为{FALSE}或{TRUE}如 A=B 表示 A 等于 BA/=B,A<>B 表示 A 不等。
