ARM常用的伪指令
ARM汇编语言伪指令

ARM汇编语言伪指令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位的常量。
ARM伪指令

ARM伪指令——中等范围的地址读取
ADRL伪指令将基于PC相对偏移的地址值或基于寄存器相对偏移的地 址值读取到寄存器中,比ADR伪指令可以读取更大范围的地址 。在汇编编 译器编译源程序时,ADRL伪指令被编译器替换成两条合适的指令。若不能 用两条指令实现,则产生错误,编译失败。 ADRL伪指令格式 ADRL{cond} register,expr
... ADRL ... Delay MOV ... R0,r14 R0,Delay 0x20 0x24
编译后的反汇编代码:
... ADD ADD ... 0xFF68 MOV ... r0,r14 r1,pc,#40 r1,r1,#FF00
使用伪指令将程序标号 Delay的地址存入R0
ADRL伪指令被汇编成两条指令
ARM汇编程序设计
AREA Word, CODE, READONLY ; name this block of code num EQU 20 ; Set number of words to be copied ENTRY start LDR r0, =src ; r0 = pointer to source block LDR r1, =dst ; r1 = pointer to destination block MOV r2, #num ; r2 = number of words to copy wordcopy LDR r3, [r0], #4 ; a word from the source STR r3, [r1], #4 ; store a word to the destination SUBS r2, r2, #1 ; decrement the counter BNE wordcopy ; ... copy more stop MOV r0, #0x18 ; angel_SWIreason_ReportException LDR r1, =0x20026 ; ADP_Stopped_ApplicationExit SWI 0x123456 ; ARM semihosting SWI AREA BlockData, DATA, READWRITE src DCD 1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8,1,2,3,4 dst DCD 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 END ; mark the first instruction to call
ARM编程进阶之一-ARM汇编伪指令

ARM编程进阶之一-ARM汇编伪指令到目前为止,我们已经具备编写较为复杂的ARM 汇编程序的能力,但要编写较为复杂且实用的程序,我们就不得不掌握ARM 汇编的伪指令(pseudo- instruction)。
千万别把汇编伪操作(directive)与汇编伪指令(pseudo- instruction)弄混了,directive 不会被编译器编译为机器指令,但pseudo- instruction 会。
而pseudo-instruction 与指令(instruction)的区别在于,1 条instruction 与1 条机器指令对应,而编译器会把1 条pseudo-instruction 编译为1 条或多条机器指令。
ARM 汇编伪指令共4 条:ldr、adr、adrl、nop1、ldr首先我们来回答基本寻址模式与基本指令一文中提出的问题。
如果我们需要mov r0, #10000 这样的指令,应该怎么办?(常数10000 不能在机器指令32bit 中的低12bit 中被表示出来)。
当你进行编译的时候,Error:All70E 的错误就会出现,如下图。
其实,这个问题很容易解决,只需要将mov r0, #10000 换为ldr r0, =10000 即可。
为什么这样就可以了呢?因为,这里的ldr r0, =10000 并非我们已经学过的ldr 指令,而是一条伪指令,编译器会将这条伪指令替换为:ldr r0, [pc, #-4]DCD 10000DCD 所分配的内存空间中存放了整数10000,该内存空间被称为literal pool,中文名称文字池。
由于整个程序都是由编译器编译的(包括文字池的分配),所以很显然编译器能够知道ldr 指令在内存中的地址与文字池在内存中的位置之间的偏移量,因此编译器就可以正确地使用以pc 为基址,采用相对寻址的ldr 指令将文字池中的数取出加载到寄存器r0 中。
由此可见,编译器对于ldr r0, =10000 这条伪指令的处理,其实质是:。
ARM汇编伪指令详解

ARM汇编伪指令详解(转载)2007-09-13 00:40ARM汇编程序分析过程中,比较难理解的是他的伪操作、宏指令和伪指令。
在读vivi时遇到很多不懂的,所以在此对引导程序中出现伪操作、宏指令和伪指令进行总结,*****************************************************一、GET option.s// GET和INCLUDE功能相同功能:引进一个被编译过的文件。
格式:GET filename其中:fiename 汇编时引入的文件名,可以有路径名。
GET符号在汇编时对宏定义,EQU符号以及存储映射时是很有用的,在引入文件汇编完以后,汇编将从GET符号后开始。
在被引入的文件中可能有GET符号再引入其他的文件。
GET符号不能用来引入目标文件。
*****************************************************二、INTPND EQU 0x01e00004//EQU可以用“*”代替,在阅读源程序时注意。
功能:对一个数字常量赋予一个符号名。
格式:name EQU expression其中:name 符号名。
Expression 寄存器相关或者程序相关的固定值。
使用EQU定义常量,与C语言中用#define定义一个常量相同。
例:num EQU 2 ;数字2赋予符号num*****************************************************三、GBLL THUMBCODE[ {CONFIG} = 16THUMBCODE SETL {TRUE}CODE32|THUMBCODE SETL {FALSE}][ THUMBCODECODE32 ;for start-up code for Thumb mode]//其中[=IF ,|=ELSE ,]= ENDIF, CODE32 表明一下操作都在ARM状态。
第3章 3.4 ARM伪指令及应用程序举例

局部变量的作用范围为:包含该局部变量的宏代码的 一个实例
August 9, 2013
Neusoft Institute of Information
• 3、 SETA,SETL,SETS • 用于给ARM程序中的变量赋值。 –SETA:给一个算术变量赋值。 –SETL:给一个逻辑变量赋值。 –SETS:给一个串变量赋值。 • 语法格式: variable <setx> expression expression:赋给变量的值。
Neusoft Institute of Information
• 1、GBLA,GBLL,GBLS • 用于声明一个ARM程序中的全局变量,并将其初始化。 –GBLA:声明一个全局算术变量,并初始化成0。 –GBLL:声明一个全局逻辑变量,并初始化成 {FALSE}。 –GBLS:声明一个全局串变量,并初始化成空串 “”。 • 语法格式: <gblx> variable
„„
MOV R0,R14
August 9, 2013
Neusoft Institute of Information
3、LDR ——大范围的地址读取 LDR伪指令用于加载32位立即数或一个地 址值到指定的寄存器。在汇编编译源程序时,LDR伪 指令被编译器替换成一条合适的指令。若加载的常 数未超过MOV或MVN的范围,则使用MOV或MVN指令代 替该LDR伪指令,否则汇编器将常量放入文字池,并 使用一条程序相对偏移的LDR指令从文字池读出常量。 语法格式: LDR{cond} register,=expr 其中: Register:加载的目标寄存器。 expr:32位常量或地址表达式。
August 9, 2013
Neusoft Institute of Information
嵌入式系统原理与应用常用Arm汇编伪指令

常用Arm汇编伪指令
在Arm汇编语言程序中,有一些特殊指令用于对汇编过程进行控制,这些指令不是可执行指令也没有对应的机器码,只用于汇编过程中为汇编程序提供汇编信息,这些指令称为伪指令,它们所完成的操作称为伪操作。
常用的伪指令有以下几种:符号定义伪指令、数据定义伪指令、汇编控制伪指令、信息报告伪指令以及杂项伪指令。
下面列出了上述几种常用的Arm汇编伪指令。
1. 符号定义伪指令
符号定义伪指令用于定义汇编程序中的变量、对变量赋值以及定义寄存器别名等操作。
表2.1 符号定义伪指令
2. 数据定义伪指令
数据定义伪指令一般用于为特定的数据分配存储单元,并可对分配的存储单元进行初始化。
表2.2 数据定义伪指令
3. 汇编控制伪指令
汇编控制伪指令用于控制汇编程序的执行流程。
表2.3 汇编控制伪指令
4. 信息报告伪指令
报告伪指令用于汇编报告指示。
表2.4 信息报告伪指令
5. 杂项伪指令
杂项伪指令是未包含在表2.1至2.4中且在汇编程序设计中常用的伪指令。
表2_5 杂项伪指令。
[计算机]ARM伪指令
![[计算机]ARM伪指令](https://img.taocdn.com/s3/m/8a58ec3e6bd97f192279e972.png)
ARM伪指令一、符号定义(Symbol Definition )伪指令 (2)1、GBLA、GBLL 和GBLS (2)2、LCLA、LCLL 和LCLS (2)3、SETA、SETL 和SETS (3)4 、RLIST (3)二、数据定义(Data Definition )伪指令 (3)1、DCB (4)2、DCW(或DCWU) (4)3、DCD(或DCDU) (4)4、DCFD(或DCFDU) (5)5、DCFS(或DCFSU) (5)6、DCQ(或DCQU) (5)7、SPACE (5)8、MAP (6)9、FILED (6)三、汇编控制(Assembly Control )伪指令 (6)1、IF、ELSE、ENDIF (6)2、WHILE、WEND (7)3、MACRO、MEND (7)4、MEXIT (8)四、其他常用的伪指令 (8)1、AREA (8)2、ALIGN (9)3、CODE16、CODE32 (9)4、ENTRY (10)5、END (10)6、EQU (10)7、EXPORT(或GLOBAL) (10)8、IMPORT (11)9、EXTERN (11)10、GET(或INCLUDE) (11)11、INCBIN (12)12、RN (12)13、ROUT (12)五、以“。
”开头的伪指令 (13)1、.word (13)2、.balignl (13)在 ARM 汇编语言程序里,有一些特殊指令助记符,这些助记符与指令系统的助记符不同,没有相对应的操作码,通常称这些特殊指令助记符为伪指令,他们所完成的操作称为伪操作。
伪指令在源程序中的作用是为完成汇编程序作各种准备工作的,这些伪指令仅在汇编过程中起作用,一旦汇编结束,伪指令的使命就完成。
在 ARM 的汇编程序中,有如下几种伪指令:符号定义伪指令、数据定义伪指令、汇编控制伪指令、宏指令以及其他伪指令。
一、符号定义(Symbol Definition )伪指令符号定义伪指令用于定义 ARM 汇编程序中的变量、对变量赋值以及定义寄存器的别名等操作。
ARM GUN 伪指令

1.宏定义.macro 宏名 参数名列表 @伪指令.macro定义一个宏宏体.endm @.endm表示宏结束如果宏使用参数,那么在宏体中使用该参数时添加前缀“\”。
宏定义时的参数还可以使用默认值。
可以使用.exitm伪指令来退出宏。
2.段定义section伪操作用户可以通过.section伪操作来自定义一个段,格式如下:.section section_name [, "flags"[, %type[,flag_specific_arguments]]]flag的值为 a 允许段 w 可写段 x 执行段预定义的段名 .text @代码段 .data @初始化数据段 .bss @未初始化数据段定义入口点 :.globl _start_start:注意: 源程序中.bss段应该在.text之前当用预定义段名可以直接使用,当是自定义时段定义要完整。
3.数据定义伪操作: .byte 1b,.short 2b,.long 4b,.quad 8b,.float,.string/.asciz/. ascii,重复定义伪操作.rept,赋值语句.equ/.set注意:.ascii伪操作定义的字符串需要自行添加结尾字符'\0'4. 函数定义伪操作:格式函数名:函数体返回语句一般的,函数如果需要在其他文件中调用, 需要用到.global伪操作将函数声明为全局函数。
为了不至于在其他程序在调用某个C函数时发生混乱,对寄存器的使用我们需要遵循APCS准则。
函数编译器将处理为函数代码为一段.global的汇编码。
5.常数1)十进制数以非0数字开头,如:123和9876;2)二进制数以0b开头,其中字母也可以为大写;3)八进制数以0开始,如:0456,0123;4)十六进制数以0x开头,如:0xabcd,0X123f;5)字符串常量需要用引号括起来,中间也可以使用转义字符,如: "You are welcome!\n";6)当前地址以"."表示,在汇编程序中可以使用这个符号代表当前指令的地址;7)表达式:在汇编程序中的表达式可以使用常数或者数值, "-"表示取负数, "~"表示取补,"<>"表示不相等,其他的符号如:+、-、*、/、%、<、<<、>、>>、|、&、^、!、==、>=、<=、&&、||跟C语言中的用法相似。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
在线学习好工作/
ARM常用的伪指令
AREA就是常见的伪指令之一。
AREA是声明区域段,数据区,代码区等等。
什么是数据段呢?数据段是来定义数据结构体的。
格式是AREA
test,CODE,READONLY。
还有指令CODE16、CODE32,格式就直接写上就是。
目的是声明以下是32位还是16位指令,注意不是切换arm和thunmb模式。
如果是16位,那就是thunmb指令。
操作:这是之前的,如果在这里做一个声明,CODE32,也就是表示ARM指令。
如果这里CODE16,就表示一下代码是16位指令,也就是thunmb指令,
也就是说在编译的时候会按照thunmb指令来进行汇编。
大家注意一点,在这里通过这个切换,并不会改变处理器的运行的处理模式。
不会把ARM指令状态切换为thunmb指令状态。
这个切换是在状态寄存器里面去切换T。
这个地方只是告诉汇编器而已,所以并不会更换运行时候的指令切换方式。
entry:entry伪指令用于指定汇编程序的入口点。
在一个完整的汇编程序中至少要一个entry(也可以多个,当有多个entry时,程序的真正入口点由链接器指定),但在一源文件里最多只能有一个entry(可以没有)。
END:END伪指令用于通知编译器已经到了源程序的结尾。
EQU:EQU伪指令用于为程序中的常量、标号等定义一个等效的字符名称,类似于c语言的#define。
格式是UARTLCON0EQU.0x3FFD00。
比方说:SUNDYCON1
EQU0x3200000,我们定义了一个常量,这个常量可以拿来直接用。
这里注意一点,我们编译先看一下。
这里就出错了。
未知的操作代码。
这是怎么回事?汇编这一块,跟自己的汇编器,编译器是有关系的,有时跟ID的环境都有关。
在ARM里面,特别ADS里面,他对是否顶头,和Tab要求非常严格。
因为我们这里不是一个标准指令,它会看第一个是什么操作码,这里操作码是不识别的,所以这里就出错认不出来。
这是应该怎样做呢?首先把SUNDY顶头,就可以知道只是个伪指令。
EXPOET:export伪指令用于程序中声明一个全局的标号,该标号可在其他的文件中引用。
export可用GLOBAL代替。
标号在程序中区分大小写,weak选项声明其他的同名标号优先于该标号被引用。
IMPORT相当于静态引用。
IMPORT伪指令用于通知编译器要使用的标号在其他的源文件中定义,但要在当前源文件中引用,而且无论当前源文件是否引用该标号,该标号都会被加入到当前源文件的符号表中。
EXTERN相当于动态引用。
EXTERN伪指令用于通知编译器要使用的标号在其他的源文件中定义,但要在当前的源文件中引用,如果当前源文件实际未引用该标号,该标号就不会被加到当前源文件的符号表中。
GET相当于引用文件。
GET伪指令用于将一个源文件包含到当前的源文件中,并将被包含的源文件在当前位置进行汇编处理。
可以使用INCLUDE代替GET。
RN:RN伪指令用于给一个寄存器定义一个别名。
采用这种方式可以方便程序员记忆该寄存器的功能。
其中,名称为给寄存器定义的别名,表达式为寄存器的编码。
RN的格式:name RN Rn。
鉴于这种方式,这里应该顶头。
比方说这里给一个别名SRegister,SRegister RN R0。
再用就可以MOV SRegjister#0x12。
这样可以通过SRegister来代替R0寄存器。
这就是关于常用的伪指令的符号。
这些都很容易理解,就只有EQU,其实EQU只要记住类似于define就可以了。
汇编语言程序中常见的符号。
之前学过的有很多条件操作符号,比如,EQ,LT,GT,NE等等,用这些东西进行中一些数据运算。
有时需要把某一个值临时存到一个临时的变量里,然后回过头在用到这个变量。
以前是没有办法的,只能去操作,定一些值,把这些值存储到临时寄存器里面,然后用完再把它取出来。
这样很麻烦。
来源:麦子学院
原文链接:/wiki/arm/common/。