Top Banner
© 2005 博博博博 BEIJNG UNIVERSAL PIONEERING TECHNOLOGY Co . , LTD 博博博博 博博博博 ARM 博博博博博博
195

ARM 指令集与编程

Mar 15, 2016

Download

Documents

sonya-mcpherson

ARM 指令集与编程. 目录. 总体介绍:指令分类,特点,格式,条件码 ARM 指令寻址方式 数据处理指令:数据传输指令,算术指令,逻辑指令,比较指令,乘法指令 ( 略 ) ,前导零计数 ( 略 ) 程序状态访问指令 跳转指令 单数据访存指令 多数据访存指令 其它指令:信号量操作指令,异常中断产生指令,协处理器指令 ( 略 ) 伪指令 基于 ARM 的编程. 1 总体介绍:指令分类,特点,格式,条件码. 1.1 指令分类. ARM 指令集总体分为 6 类指令 数据处理指令:数据传输指令,算术指令,逻辑指令,比较指令,乘法指令,前导零计数。 - PowerPoint PPT Presentation
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: ARM 指令集与编程

© 2005 博创科技 北 京 博 创 兴 业 科 技 有 限 公 司BEIJNG UNIVERSAL PIONEERING TECHNOLOGY Co . , LTD

博创科技 嵌入互动

ARM 指令集与编程

Page 2: ARM 指令集与编程

博创科技 嵌入互动

© 2005 博创科技

目录1. 总体介绍:指令分类,特点,格式,条件码2. ARM 指令寻址方式3. 数据处理指令:数据传输指令,算术指令,逻辑指令,比较指令,乘法指令 ( 略 ) ,前导零计数 ( 略 )4. 程序状态访问指令5. 跳转指令6. 单数据访存指令7. 多数据访存指令8. 其它指令:信号量操作指令,异常中断产生指令,协处理器指令

( 略 )9. 伪指令10. 基于 ARM 的编程

Page 3: ARM 指令集与编程

© 2005 博创科技 北 京 博 创 兴 业 科 技 有 限 公 司BEIJNG UNIVERSAL PIONEERING TECHNOLOGY Co . , LTD

博创科技 嵌入互动

1 总体介绍:指令分类,特点,格式,条件码

Page 4: ARM 指令集与编程

博创科技 嵌入互动

© 2005 博创科技

1.1 指令分类 ARM 指令集总体分为 6 类指令

数据处理指令:数据传输指令,算术指令,逻辑指令,比较指令,乘法指令,前导零计数。 程序状态访问指令: mrs 和 msr 。 跳转指令: b 和 bl 。 访存指令:单数据访存指令,多数据访存指令,信号量操作指令。 异常中断产生指令: swi 和 bkpt 。 协处理器指令。

Page 5: ARM 指令集与编程

博创科技 嵌入互动

© 2005 博创科技

1.2 指令特点 所有指令都是 32bit 。 大多数指令都在单周期内完成。 所有指令都可以条件执行。 load/store 体系结构。 指令集可以通过协处理器扩展

Page 6: ARM 指令集与编程

博创科技 嵌入互动

© 2005 博创科技

1.3 ARM 指令的格式

<Opcode>{<cond>}{s} <Rd>, <Rn>, <Operand2>

Cond :指令的条件码。 Opcode :指令操作码。 S :操作是否影响 cpsr 。 Rn :包含第一个操作数的寄存器编码。 Rd :目标寄存器编码。 Operand2 :第 2 操作数。

Cond 001 Opcode S Rn Rd Operand2

0111215161920212425272831 78

Page 7: ARM 指令集与编程

博创科技 嵌入互动

© 2005 博创科技

1.3 ARM 指令的格式 ( 续 )

Page 8: ARM 指令集与编程

博创科技 嵌入互动

© 2005 博创科技

1.4 ARM 指令的条件执行所有的 ARM 指令可包含一个可选的条件码,只有在 cpsr 中的条件标志位满足指定的条件时,指令才会被执行。不符合条件的代码依然占用一个时钟周期(相当于一个NOP 指令)。

// r0, r1, r2, r3, r4 : a, b, c, d, ecmp r0, r1cmpeq r2, r3addeq r4, r4, #1

if ( (a == b) && (c == d) ) {

e++;}

Page 9: ARM 指令集与编程

博创科技 嵌入互动

© 2005 博创科技

1.4.1 ARM 指令的条件域

EQ/NE: 等于 / 不等于 (equal / not equal) HS/LO: 无符号数高于或等于 / 无符号数小于 (higher or same/lower) HI/LS: 无符号数高于 / 无符号数低于或等于 (higher/lower or same) GE/LT: 有符号数大于或等于 / 有符号数小于 (greater or equal / less than) GT/LE: 有符号数大于 / 有符号数小于或等于 (greater than / less or equal) MI/PL: 负 / 非负 VS/VC: 溢出 / 不溢出 (overflow set / overflow clear) CS/CC: 进位 / 无进位 (carry set / carry clear)

Page 10: ARM 指令集与编程

博创科技 嵌入互动

© 2005 博创科技

1.4.2 ARM 指令的条件码

0000 EQ Z 置位 相等 / 等于 0

0001 NE Z 清 0 不等0010 CS/HS C 置位 进位 / 无符号高于或等于0011 CC/LO C 清 0 无进位 / 无符号低于0100 MI N 置位 负数0101 PL N 清 0 非负数0110 VS V 置位 溢出0111 VC V 清 0 无溢出

Page 11: ARM 指令集与编程

博创科技 嵌入互动

© 2005 博创科技

1.4.2 ARM 指令的条件码 ( 续 )

1000 HI C 置位且 Z 清 0 无符号高于1001 LS C 清 0 或 Z 置位 无符号低于或等于1010 GE N 等于 V 有符号大于或等于1011 LT N 不等于 V 有符号小于1100 GT Z 清 0 且 N 等于 V 有符号大于1101 LE Z 置位或 N 不等于 V 有符号小于或等于1110 AL 任何状态 总是( always )1111 NV 无 从不( never )

注: AL 是默认的, NV 不建议使用。

Page 12: ARM 指令集与编程

博创科技 嵌入互动

© 2005 博创科技

目录1. 总体介绍:指令分类,特点,格式,条件码2. ARM 指令寻址方式3. 数据处理指令:数据传输指令,算术指令,逻辑指令,比较指令,乘法指令 ( 略 ) ,前导零计数 ( 略 )4. 程序状态访问指令5. 跳转指令6. 单数据访存指令7. 多数据访存指令8. 其它指令:信号量操作指令,异常中断产生指令,协处理器指令

( 略 )9. 伪指令10. 基于 ARM 的编程

Page 13: ARM 指令集与编程

© 2005 博创科技 北 京 博 创 兴 业 科 技 有 限 公 司BEIJNG UNIVERSAL PIONEERING TECHNOLOGY Co . , LTD

博创科技 嵌入互动

2 ARM 指令寻址方式

Page 14: ARM 指令集与编程

博创科技 嵌入互动

© 2005 博创科技

2.1 寄存器寻址ADD R0,R1,R2 ; R0 =R1+R2 这条指令将两个寄存器( R1 和 R2 )的内容相加,结果放入第 3 个寄存器 R0 中。必须注意写操作数的顺序,第 1 个是结果寄存器,然后是第一操作数寄存器,最后是第二操作数寄存器。

Page 15: ARM 指令集与编程

博创科技 嵌入互动

© 2005 博创科技

2.2 立即寻址指令中在操作码字段后面的地址码部分不是通常意义上的操作数地址,而是操作数本身。 ADD R3,R3,#1 ; R3= R3+1 AND R8,R7,#0xff ; R8= R7[7:0] 第 2 个源操作数为一个立即数,以“ #” 为前缀,十六进制值以在“ #” 后加“ 0x” 或“ &” 表示。

Page 16: ARM 指令集与编程

博创科技 嵌入互动

© 2005 博创科技

2.3 寄存器移位寻址这种寻址方式是 ARM 指令集特有的。第 2 个寄存器操作数在与第 1 个操作数结合之前,选择进行移位操作。 ADD R3,R2,R1,LSL #3 ; R3 =R2+8×R1

寄存器 R1 的内容逻辑左移 3 位,再与寄存器 R2 内容相加,结果放入 R3 中。

Page 17: ARM 指令集与编程

博创科技 嵌入互动

© 2005 博创科技

逻辑移位 LSL :逻辑左移( Logical Shift Left )。寄存器中字的低端空出的位补 0 。 ·LSR :逻辑右移( Logical Shift Right )。寄存器中字的高端空出的位补 0 。 ·ASR :算术右移( Arithmetic Shift Right )。算术移位的对象是带符号数,在移位过程中必须保持操作数的符号不变。若源操作数为正数,则字的高端空出的位补 0 。若源操作数为负数,则字的高端空出的位补 1 。 ·ROR :循环右移( Rotate Right )。从字的最低端移出的位填入字的高端空出的位。 ·RRX :扩展为 1 的循环右移( Rotate Right Extended by 1 plac

e )。操作数右移一位,空位(位 [31] )用原 C 标志填充。

Page 18: ARM 指令集与编程

博创科技 嵌入互动

© 2005 博创科技移位操作过程

Page 19: ARM 指令集与编程

博创科技 嵌入互动

© 2005 博创科技

移位操作 在任何数据处理指令中 ,第二寄存器操作数可以有应用该操作数的移位操作 . 逻辑移位

LSL:逻辑左移字的最小位空位清零 LSR:LSR: 逻辑右移字的最大位空位清零逻辑右移字的最大位空位清零 ..

Page 20: ARM 指令集与编程

博创科技 嵌入互动

© 2005 博创科技

移位操作 (cont’d) 算术移位

ASR: 正数的 ASR= LSR 循环移位 : ROR, RRX

Page 21: ARM 指令集与编程

博创科技 嵌入互动

© 2005 博创科技

指令中的地址码给出某一通用寄存器的编号。在被指定的寄存器中存放操作数的有效地址,而操作数则存放在存储单元中,即寄存器为地址指针。 LDR R0,[R1] ; R0 =[R1]

STR R0,[R1] ; [R1] = R0 寄存器间接寻址使用一个寄存器(基址寄存器)的值作为存储器的地址。

2.4 寄存器间接寻址

Page 22: ARM 指令集与编程

博创科技 嵌入互动

© 2005 博创科技

2.5 变址寻址 变址寻址就是将基址寄存器的内容与指令中给出的位移量相加,形成

操作数有效地址。变址寻址用于访问基址附近的存储单元,包括: 基址加偏移 基址加索引寻址。 寄存器间接寻址是偏移量为 0 的基址加偏移寻址。

Page 23: ARM 指令集与编程

博创科技 嵌入互动

© 2005 博创科技

基址加偏移寻址中的基址寄存器包含地址,需加(或减)(最大 4 KB )的偏移来计算访问的地址。

LDR R0,[R1,#4] ; R0 =[R1+4]

这是前索引寻址方式。 带自动索引的前索引寻址。 LDR R0,[R1,#4]! ; R0= [R1 + 4]

; R1 =R1+4

“ !”符号表明指令在完成数据传送后应该更新基址寄存器

Page 24: ARM 指令集与编程

博创科技 嵌入互动

© 2005 博创科技

后索引寻址。基址不带偏移作为传送的地址,传送后自动索引。 LDR R0,[R1],#4 ; R0= [R1] ; R1= R1+4

基址加索引寻址有时指令指定一个基址寄存器,再指定另一个寄存器(索引),其值作为偏移加到基址上形成存储器地址。例如指令:

LDR R0,[R1,R2] ; R0= [R1+R2]

Page 25: ARM 指令集与编程

博创科技 嵌入互动

© 2005 博创科技

2.6 块拷贝寻址 ARM 支持两种不同角度的块寻址机制,两者都映射到相同的基本指令——多寄存器

传送指令。多寄存器传送指令可以用于把一块数据从存储器的某一位置拷贝到另一位置;基于数据是存储在基址寄存器的地址之上还是之下,地址是在存储第 1 个值之前还是之后增加还是减少。

下 图说明了 4 种不同情况的多字节传送指令传送前后的内存变化,以及使用自动寻址时如何修改基址寄存器。指令执行前的基寄存器是 R9 ,指令执行后的基寄存器是R9’ 。

Page 26: ARM 指令集与编程

博创科技 嵌入互动

© 2005 博创科技

STMIA R9! , {R0 , R1 , R5} STMIB R9! , { R0 , R1 , R5 }

R9'

R9

101816R5R1R0 100C16

100016

R9'

R9

101816R5R1R0

100C16

100016

Page 27: ARM 指令集与编程

博创科技 嵌入互动

© 2005 博创科技

STMDA R9! , {R0 , R1 , R5} STMDB R9! , { R0 , R1 , R5 }

R9'

R9

101816

R5R1R0

100C16

100016 R9'

R9

101816

R5R1R0

100C16

100016

Page 28: ARM 指令集与编程

博创科技 嵌入互动

© 2005 博创科技

2.7 堆栈寻址 堆栈是一种按特定顺序进行存取的存储区。“后进先出”( LIFO )。栈指针所指定的存储单元就是堆栈的栈顶。存储器堆栈可分为两种:

· 向上生长:即向高地址方向生长,称为递增堆栈( ascending stack )。

· 向下生长:即向低地址方向生长,称为递减堆栈( descending stack )。

堆栈指针指向最后压入堆栈的有效数据项,称为满堆栈( full stack )。堆栈指针指向下一个数据项放入的空位置,称为空堆栈( empty stack )。

Page 29: ARM 指令集与编程

博创科技 嵌入互动

© 2005 博创科技

ARMARM 对堆栈的使用一般用多寄存器传送指令,是一种有效对堆栈的使用一般用多寄存器传送指令,是一种有效的保存处理器状态和多字节传送的有效方式。的保存处理器状态和多字节传送的有效方式。 ARMARM 硬件中的硬件中的堆栈分为以下四种类型:堆栈分为以下四种类型:①① 满向上生长型(满向上生长型( FAFA ):堆栈按高地址方向生长,当前堆栈):堆栈按高地址方向生长,当前堆栈指针指向最高有效值;指针指向最高有效值;②② 空向上生长型(空向上生长型( EAEA )) :堆栈按高地址方向生长,当前堆栈:堆栈按高地址方向生长,当前堆栈指针指向第一个空值;指针指向第一个空值;③③ 满向下生长型(满向下生长型( FDFD ) :堆栈按低地址方向生长,当前堆栈) :堆栈按低地址方向生长,当前堆栈指针指向最低有效值;指针指向最低有效值;④④ 空向下生长型(空向下生长型( EDED ) :堆栈按低地址方向生长,当前堆) :堆栈按低地址方向生长,当前堆栈指针指向第一个空值。栈指针指向第一个空值。

Page 30: ARM 指令集与编程

博创科技 嵌入互动

© 2005 博创科技

若 R3~R9 保存的是有用的值,就应该把它们压进堆栈进行保存。即 STMFD R13!,{R3-R9} ; 存储寄存器到堆栈 。。。。。。 LDMFD R13!,{R3-R9} ; 从堆栈恢复 其中第一条和最后一条指令的“ FD” 表明是满递减堆栈寻址方式。

Page 31: ARM 指令集与编程

博创科技 嵌入互动

© 2005 博创科技

堆栈和块拷贝角度的多寄存器加载和存储指令映射

Page 32: ARM 指令集与编程

博创科技 嵌入互动

© 2005 博创科技

堆栈用 一般数据存取 L 位 存取

P 位前变址 / 后变址

U 位加 /减

空向下生长型(之前增量) LDMED LDMIB 1 1 1

满向下生长型(之后增量) LDMFD LDMIA 1 0 1

空向上生长型(之前增量) LDMEA LDMDB 1 1 0

满向上生长型(之后增量) LDMFA LDMDA 1 0 0

满向上生长型(之前增量) STMFA STMIB 0 1 1

空向上生长型(之后增量) STMEA STMIA 0 0 1

空向下生长型(之前增量) STMFD STMDB 0 1 0

满向下生长型(之后增量) STMED STMDA 0 0 0

Page 33: ARM 指令集与编程

博创科技 嵌入互动

© 2005 博创科技

2.8 相对寻址 相对寻址是变址寻址的一种变通,由程序计数器 PC 提供基地址。指令中的地址码字段作为位移量。 BL SUBR ; 转移到 SUBR … … ; 返回到此 … … SUBR … ; 子程序入口地址 MOV PC , R14 ; 返回

Page 34: ARM 指令集与编程

博创科技 嵌入互动

© 2005 博创科技

目录1. 总体介绍:指令分类,特点,格式,条件码2. ARM 指令寻址方式3. 数据处理指令:数据传输指令,算术指令,逻辑指令,比较指令,乘法指令 ( 略 ) ,前导零计数 ( 略 )4. 程序状态访问指令5. 跳转指令6. 单数据访存指令7. 多数据访存指令8. 其它指令:信号量操作指令,异常中断产生指令,协处理器指令

( 略 )9. 伪指令10. 基于 ARM 的编程

Page 35: ARM 指令集与编程

© 2005 博创科技 北 京 博 创 兴 业 科 技 有 限 公 司BEIJNG UNIVERSAL PIONEERING TECHNOLOGY Co . , LTD

博创科技 嵌入互动

3 ARM 数据处理指令

Page 36: ARM 指令集与编程

博创科技 嵌入互动

© 2005 博创科技

3 数据处理指令 数据传输指令: mov 和 mvn 算数指令: add、 adc、 sub、 sbc , rsb 和 rsc 逻辑指令: and、 orr、 eor 和 bic 比较指令: cmp、 cmn、 tst 和 teq

Page 37: ARM 指令集与编程

博创科技 嵌入互动

© 2005 博创科技

3.1 数据处理指令的特点 所有的操作数要么来自寄存器,要么来自立即数,不会来自内存。 如果有结果,则结果一定是为 32 位宽,并且放在一个寄存器中,不会写入内存。(有一个例外:长乘法指令产生 64 位结果) 每一个操作数寄存器和结果寄存器都在指令中独立指出,即: ARM 指令采用 3 地址模式: <Operation> Rd, Rn, Rm

Page 38: ARM 指令集与编程

博创科技 嵌入互动

© 2005 博创科技

3.2 四种寻址方式和 s 后缀

add r0, r1, r2

add r0, r1, #0xff

add r0, r1, r1, LSL r2

Cond S Rn Rd 第 2 操作数078111215161920

opcode

2124

00X

25272831

#immed_8#rot

07811

0 0 0 0 0 0 0 0 Rm

03411

方式 1 : #immed

方式 2 : Rm

0 0 0 0 Rm

03411

Rs

78

方式 3 : Rm LSL Rs

shift Rm

03411

#immed_5

67方式 4 : Rm LSL #immed_5( #immed_5 取值范围 0-31 )add r0, r1, r1, LSL #31

Page 39: ARM 指令集与编程

博创科技 嵌入互动

© 2005 博创科技

3.2.1 四种寻址方式的硬件支持•寄存器,可能需要移位。•如需移位,移位值可为:

•5bit 的无符号整数( 0-31 )•在指令的最低字节指定的另一寄存器

•立即数• 8 比特数•8 比特数循环右移偶数位•右移位数由汇编器自动计算

Page 40: ARM 指令集与编程

博创科技 嵌入互动

© 2005 博创科技

3.2.2 立即数方式 ARM 指令中的立即数,由一个 8bit 的常数循环右移偶数位得到:

立即数 = ( 0->255) 循环右移 2N 位 例子:

合法立即数: 0x3fc , 0x0 , 0xf0000000 , 0xf0000001 非法立即数: 0x1fe , 0xffff , 0x1010 , 0xf0000010

Page 41: ARM 指令集与编程

博创科技 嵌入互动

© 2005 博创科技

3.2.2 立即数方式 ( 续 )

同一个立即数可能有多个表示方法。如: 0x3f0 = 0x3f 循环右移 28 位 0x3f0 = 0xfc 循环右移 30 位

对立即数的编码规则: 如果立即数在 0 – 0xff 之间,移位数为 0 。 否则,就取决于编译器了。指令“ mov r0, #0x3f0” 在 ADS1.2 中被编译为 0xe3a00ffc ,在 arm-elf-gcc-2.95.3 中被编译为 0xe3a00

e3f 。

Page 42: ARM 指令集与编程

博创科技 嵌入互动

© 2005 博创科技

3.2.2 立即数方式 ( 续 )

对于有互补操作的指令,编译器可以做智能的转换,比如: mvn r1, 0xffffff00 -> mov r1, 0xff add r1, r1, #0xffffff00 -> sub r1, r1, #0x100 adc r1, r1, #0xffffff00 -> sbc r1, r1, #0xff and r1, r1,#0xffffff00 -> bic r1, r1, #0xff

这样,一些原本非法的立即数也可以正常编译通过。如果一个立即数,经过上述转换后是合法的,那么它也可以用在数据操作指令中。

Page 43: ARM 指令集与编程

博创科技 嵌入互动

© 2005 博创科技

3.2.3 寄存器移位寻址ASR 算术右移LSL 逻辑左移LSR 逻辑右移ROR循环右移RRX 扩展的循环右移

Page 44: ARM 指令集与编程

博创科技 嵌入互动

© 2005 博创科技

3.2.3 寄存器移位寻址(续) 如果移位的位数由立即数( 5bit ,取值范围 0 - 31 )给出,就叫作 immediate specified shift ;如果由 Rs 的低 5 位决定,就叫做

register specified shift 。 Register specified shift 的两点问题:

不能使用 pc :如果将 pc 寄存器用在 Rn , Rd , Rm 和 Rs的位置上时,会产生不可预知的结果。 额外代价( overhead ):需要更多的周期才能完成指令,因为 ARM没有能力一次读取 3 个寄存器。

Immediate specified shift 没有上述问题。

Page 45: ARM 指令集与编程

博创科技 嵌入互动

© 2005 博创科技

3.2.3 寄存器移位寻址(续) 在 register specified shift 寻址方式下使用 pc 寄存器,编译器提示如下警告:

在 ADS1.2 种编译产生如下警告之一: Warning A1477W : This register combination results in UNPREDICT

ABLE behavior Warning : A1320E: Undefined effect (using PC as Rn or Rm in register

specified shift) Warning : A1319E: Undefined effect (using PC as Rs)

但是在 arm-elf-gcc-2.95.3 中没有报告错误。

Page 46: ARM 指令集与编程

博创科技 嵌入互动

© 2005 博创科技

3.2.4 后缀 s

数据处理指令可以选择 s 后缀,以影响状态标志。但是比较指令( cmp、 cmn、 tst 和 teq )不需要后缀 s ,它们总会直接影响 cpsr 中的状态标志。

在数据操作指令中,除了比较指令以外,其它的指令如果带有 s 后缀,同时又以 pc 为目标寄存器进行操作,则操作的同时从 spsr恢复 cpsr 。比如: movs pc, #0xff /* cpsr = spsr; pc = 0xff */ adds pc, r1, #0xffffff00 /* cpsr = spsr; pc = r1 + 0xffffff00 */ ands pc, r1, r2 /* cpsr = spsr; pc = r1 & r2; */

如果在 user 或者 system模式下使用带有 s 后缀的数据操作指令,同时以 pc 为目标寄存器,那么会产生不可预料的结果。因为 user 和 system模式下没有 spsr 。

Page 47: ARM 指令集与编程

博创科技 嵌入互动

© 2005 博创科技

3.3 数据传输指令 语法

<Operation>{<cond>}{s} <Rd>, #<immed> <Operation>{<cond>}{s} <Rd>, <Rm> <Operation>{<cond>}{s} <Rd>, <Rm>, LSL #<immed_5> <Operation>{<cond>}{s} <Rd>, <Rm>, LSL <Rs>

伪代码if ConditionPassed(cond) then

Rd = 第 2 操作数if s == 1 and Rd == pc then

cpsr == spsrelse if s == 1 then

set NZCV flags in cpsr

Page 48: ARM 指令集与编程

博创科技 嵌入互动

© 2005 博创科技

3.3 数据传输指令(续) 举例

mov r0, r1 /* r0 = r1 ,不修改 cpsr */ mov r0, #0x0 /* r0 = 0 ,不修改 cpsr */ movs r0, #0x0 /* r0 = 0 ,同时设置 cpsr 的 Z 位 */ movs r0, # -10 /* r0 = 0xfffffff6 ,同时设置 cpsr 的 N 位

*/ mvn r0, r2 /* r0 = NOT r2 ,不修改 cpsr */ mvn r0, 0xffffffff /* r0 = 0x0 ,不修改 cpsr */ mvns r0, 0xffffffff /* r0 = 0x0 ,同时设置 cpsr 的 Z 位 */ mov r0, r1, LSL #1 /* r0 = r1 << 1 */ mov r0, r1, LSR r2 /* r0 = r1 >> r2 */

Page 49: ARM 指令集与编程

博创科技 嵌入互动

© 2005 博创科技

3.3 数据传输指令(续) 说明

mvn 意为“取反传输”,它把源寄存器的每一位取反,将得到的结果写入结果寄存器。 movs 和 mvns 指令对 pc 寄存器赋值时有特殊含义,表示要求在赋值的同时从 spsr 中恢复 cpsr 。 对于 mov 和 mvn 指令,编译器会进行智能的转化。比如指令“ mov r1, 0xfff

fff00” 中的立即数是非法的。在编译时,编译器将其转化为“ mvn r1, 0xff” ,这样就不违背立即数的要求。所以对于 mov 和 mvn 指令,可以认为:合法的立即数反码也是合法的立即数。

Page 50: ARM 指令集与编程

博创科技 嵌入互动

© 2005 博创科技

3.4 算术指令 语法

<Operation>{<cond>}{s} <Rd>, <Rn>, #<immed> <Operation>{<cond>}{s} <Rd>, <Rn>, <Rm> <Operation>{<cond>}{s} <Rd>, <Rn>, <Rm>, LSL #<immed_5> <Operation>{<cond>}{s} <Rd>, <Rn>, <Rm>, LSL <Rs>

伪代码(以加法 add 为例)if ConditionPassed(cond) then

Rd = Rn + 第 2 操作数if s == 1 and Rd == pc then

cpsr = spsrelse if s == 1 then

set NZCV flags in cpsr

Page 51: ARM 指令集与编程

博创科技 嵌入互动

© 2005 博创科技

3.4 算术指令(续) 举例

add r0, r1, r2 /* r0 = r1 + r2 */ adc r0, r1, r2 /* r0 = r1 + r2 + carry */ sub r0, r1, r2 /* r0 = r1 – r2 */ sbc r0, r1, r2 /* r0 = r1 – r2 + carry -1 */ rsb r0, r1, r2 /* r0 = r2 – r1 */ rsc r0, r1, r2 /* r0 = r2 – r1 + carry – 1 */ add r0, r1, r1, LSL #31 /* r0 = r1 + r1 << 31 */ add r0, r1, r1, LSL r2 /* r0 = r1 + r1 << r2 */

说明 adds 和 adcs 在进位时将 cpsr 的 C 标志置 1 ;否则置 0 。 subs 和 sbcs 在产生借位时将 cpsr 的 C 标志置 0 ;否则置 1 。

Page 52: ARM 指令集与编程

博创科技 嵌入互动

© 2005 博创科技

3.5 逻辑指令 语法

<Operation>{<cond>}{s} <Rd>, <Rn>, #<immed> <Operation>{<cond>}{s} <Rd>, <Rn>, <Rm> <Operation>{<cond>}{s} <Rd>, <Rn>, <Rm> LSL #<immed_5> <Operation>{<cond>}{s} <Rd>, <Rn>, <Rm> LSL <Rs>

伪代码(以 and 为例)If ConditionPassed(cond) then

Rd = Rn AND 第 2 操作数if s == 1 and Rd == pc then

cpsr = spsrelse if s == 1 then

set NZCV flags in cpsr

Page 53: ARM 指令集与编程

博创科技 嵌入互动

© 2005 博创科技

3.5 逻辑指令(续) 举例

and r0, r1, r2 /* r0 = r1 AND r2 */ and r1, r1,#0xffffff00 /* r1 = r1 AND 0xffffff00 */ orr r0, r1, r2 /* r0 = r1 OR r2 */ eor r0, r1, r2 /* r0 = r1 XOR r2 */ bic r0, r1, r2 /* r0 = r1 AND NOT r2 */ bic r1, r1, #0x0f /* 清空 r1 的低 4 位 */ and r0, r1, r1, LSL #31 /* r0 = r1 AND (r1 << 31) */ and r0, r1, r1, LSR r2 /* r0 = r1 AND (r1 >> r2) */

Page 54: ARM 指令集与编程

博创科技 嵌入互动

© 2005 博创科技

3.6 比较指令 语法

<Operation>{<cond>} <Rn>, #<immed> <Operation>{<cond>} <Rn>, <Rm> <Operation>{<cond>} <Rn>, <Rm>, LSL #<immed_5> <Operation>{<cond>} <Rn>, <Rm>, LSL <Rs>

伪代码(以 cmp 为例)If ConditionPassed(cond) then

alu_out = Rn – 第 2 操作数 set NZCV flags in cpsr

Page 55: ARM 指令集与编程

博创科技 嵌入互动

© 2005 博创科技

3.6 比较指令(续) 举例

cmp r1, r2 /*根据 r1 – r2 的结果设置 cpsr ,结果不写回 */ cmn r1, r2 /*根据 r1 + r2 的结果设置 cpsr ,结果不写回 */ tst r1, r2 /*根据 r1 AND r2 的结果设置 cpsr ,结果不写回 */ teq r1, r2 /*根据 r1 XOR r2 的结果设置 cpsr ,结果不写回 */ cmp r2, #5 /*根据 r2 – 5 的结果设置 cpsr ,结果不写回 */ cmp r1, r2, LSL #5 /* 根据 r1 – (r2 << 5)设置 cpsr */ cmp r1, r2, LSL r3 /* 根据 r1 – (r2 << r3)设置 cpsr */

说明 如果不考虑结果的写回, cmp、 cmn、 tst 和 teq 分别等价于 subs、 adds、 an

ds 和 eors 。

Page 56: ARM 指令集与编程

博创科技 嵌入互动

© 2005 博创科技

目录1. 总体介绍:指令分类,特点,格式,条件码2. ARM 指令寻址方式3. 数据处理指令:数据传输指令,算术指令,逻辑指令,比较指令,乘法指令 ( 略 ) ,前导零计数 ( 略 )4. 程序状态访问指令5. 跳转指令6. 单数据访存指令7. 多数据访存指令8. 其它指令:信号量操作指令,异常中断产生指令,协处理器指令

( 略 )9. 伪指令10. 基于 ARM 的编程

Page 57: ARM 指令集与编程

© 2005 博创科技 北 京 博 创 兴 业 科 技 有 限 公 司BEIJNG UNIVERSAL PIONEERING TECHNOLOGY Co . , LTD

博创科技 嵌入互动

4 程序状态访问指令

Page 58: ARM 指令集与编程

博创科技 嵌入互动

© 2005 博创科技

4 程序状态访问指令 当需要修改 cpsr/spsr 的内容时,首先要读取它的值到一个通用寄存器,然后修改某些位,最后将数据写回到状态寄存器。 cpsr/spsr 不是通用寄存器,不能使用 mov 指令来读写。在 ARM 处理器中,只有 mrs 指令可以读取 cpsr/spsr ;只有 msr 可以写 cpsr/spsr 。

Page 59: ARM 指令集与编程

博创科技 嵌入互动

© 2005 博创科技

程序状态寄存器

条件标识位 N = 结果为负 Z = 结果为零 C = 进位 V = 溢出

Q 标识位 只在 5TE/J 系列中有效 指示 sticky overflow 的发生

J 标识位 仅在 5TEJ 系列中有效 J = 1: 处理器处于 Jazelle 状态

中断使能位I = 1: 禁止 IRQ.F = 1: 禁止 FIQ.

T 标识位只在 xT 系列内核中有效T = 0: 处理器处于 ARM 状态T = 1: 处理器处于 Thumb 状态

模式位指示当前处理器模式

2731

N Z C V Q28 67

I F T mode1623 815 5 4 024

f s x c

U n d e f i n e dJ

Page 60: ARM 指令集与编程

博创科技 嵌入互动

© 2005 博创科技

4.1 读指令 mrs

语法 mrs{<cond>} <Rd>, cpsr|spsr

伪代码if ConditionPassed(cond) then

if R == 1 thenRd = spsr

else Rd = cpsr

Page 61: ARM 指令集与编程

博创科技 嵌入互动

© 2005 博创科技

4.1读指令 mrs (续) 举例

mrs r0, cpsr /* 读取 cpsr到 r0 */ mrs r3, spsr /* 读取 spsr到 r3 */

说明 user 和 system模式没有 spsr ,因此这些模式下不能读取 spsr 。

Page 62: ARM 指令集与编程

博创科技 嵌入互动

© 2005 博创科技

3.2 写指令 msr 的二进制格式

0

cond R 1 0 f s x c 1111 操作数01112151619202122

1 0

2324

#

25

0 0

26272831

1 8 位立即数#rot

07811

0 0 0 0 0 0 0 0 Rm

03411

cpsr/spsr域屏蔽

立即数对准

操作数寄存器

Page 63: ARM 指令集与编程

博创科技 嵌入互动

© 2005 博创科技

3.2.1 写指令 msr 的语法 msr{<cond>} <psr>_<fields>, #<immed> msr{<cond>} <psr>_<fields>, <Rm>

<immed> 表示合法的立即数: 8bit循环右移偶数位 <psr> 代表 cpsr 或 spsr <fields> 指定传送的区域,可进一步细分 ( 只能小写 )

c 控制域字节( psr[7:0] ) x 扩展域字节( psr[15:8] ) s 状态域字节( psr[23:16] ) f 标志域字节( psr[31:24] )

Page 64: ARM 指令集与编程

博创科技 嵌入互动

© 2005 博创科技

3.2.2 写指令 msr 的伪代码 伪代码if ConditionPassed(cond) then

if opcode[25] == 1operand = 8 立即数 Rotate_Right (#rot * 2)else /* opcode[25] == 0 */

operand = Rmif R == 0 thenif field_mask[0] == 1 and InAPrivilegeMode() then cpsr[7:0] = operand[7:0]if field_mask[1] == 1 and InAPrivilegeMode() then cpsr[15:8] == operand[15:8]if field_mask[2] == 1 and InAPrivilegeMode() then cpsr[23:16] == operand[23:16]if field_mask[3] == 1 then cpsr[31:24] = operand[31:24]else /* R == 1 */if field_mask[0] == 1 and CurrentModeHasSPSR() then spsr[7:0] = operand[7:0]if field_mask[1] == 1 and CurrentModeHasSPSR() then spsr[15:8] == operand[15:8]if field_mask[2] == 1 and CurrentModeHasSPSR() then spsr[23:16] == operand[23:16]if field_mask[3] == 1 and CurrentModeHasSPSR() then spsr[31:24] = operand[31:24]

Page 65: ARM 指令集与编程

博创科技 嵌入互动

© 2005 博创科技

3.2.3 msr举例和说明 举例

msr cpsr_c, #0xd3 /* 切换到 SVC模式 */ msr cpsr_cxsf, r3 /* cpsr = r3 */

说明① user 和 system模式没有 spsr ,因此这些模式下不能对 spsr 操作。② 由于权限问题,在 user模式下对 cpsr[23:0]修改无效。③ 如果使用立即数,要使用合法的立即数。④ 程序不能同过“ msr修改 cpsr 的 T 位”来完成 ARM/Thumb 态的切换。必须使用 bx 指令,因为 bx属于分支指令,它会打断流水线,实现处理器状态切换。⑤ 如果要修改读出的值,仅修改必要的位,其它位保持不变,这样保持了最大兼容性。

Page 66: ARM 指令集与编程

博创科技 嵌入互动

© 2005 博创科技

mrs r14,CPSR ; get the processor status bic r14,r14,#CPSR_Mode_Mask orr r14,r14,#(CPSR_Mode_SVC:OR:CPSR_Int_Mask) msr cpsr_cf,r14 ; SVC 32 mode with interrupts disabled

Page 67: ARM 指令集与编程

博创科技 嵌入互动

© 2005 博创科技

目录1. 总体介绍:指令分类,特点,格式,条件码2. ARM 指令寻址方式3. 数据处理指令:数据传输指令,算术指令,逻辑指令,比较指令,乘法指令 ( 略 ) ,前导零计数 ( 略 )4. 程序状态访问指令5. 跳转指令6. 单数据访存指令7. 多数据访存指令8. 其它指令:信号量操作指令,异常中断产生指令,协处理器指令

( 略 )9. 伪指令10. 基于 ARM 的编程

Page 68: ARM 指令集与编程

© 2005 博创科技 北 京 博 创 兴 业 科 技 有 限 公 司BEIJNG UNIVERSAL PIONEERING TECHNOLOGY Co . , LTD

博创科技 嵌入互动

5 跳转指令

Page 69: ARM 指令集与编程

博创科技 嵌入互动

© 2005 博创科技

5 跳转指令 语法

b{<cond>} label bl{<cond>} label

说明 寻址范围 +32MB

Page 70: ARM 指令集与编程

博创科技 嵌入互动

© 2005 博创科技

5 跳转指令(续) 当转移指令执行时,处理器将指令中的 offset(24bit) 左移 2bit ,变成 26bit ,表示

+ 32M 的范围。 pc 从新的地址执行,流水线重新填充。 如果是“ bl” 指令,将返回地址写入 lr 寄存器。子程序返回时只需要用 lr恢复 pc就可以:

mov pc, lr “b” 指令不影响 lr 寄存器

Page 71: ARM 指令集与编程

博创科技 嵌入互动

© 2005 博创科技

ENTRY ; ; Exception vectors ; Vectortable b Reset_Handler Exceptions ldr pc, Undefined_Handler_addr ldr pc, SWI_Handler_addr ldr pc, Prefetch_Handler_addr ldr pc, Abort_Handler_addr nop ldr pc, IRQ_Handler_addr ldr pc, FIQ_Handler_addr VectortableEnd

Page 72: ARM 指令集与编程

博创科技 嵌入互动

© 2005 博创科技

目录1. 总体介绍:指令分类,特点,格式,条件码2. ARM 指令寻址方式3. 数据处理指令:数据传输指令,算术指令,逻辑指令,比较指令,乘法指令 ( 略 ) ,前导零计数 ( 略 )4. 程序状态访问指令5. 跳转指令6. 单数据访存指令7. 多数据访存指令8. 其它指令:信号量操作指令,异常中断产生指令,协处理器指令

( 略 )9. 伪指令10. 基于 ARM 的编程

Page 73: ARM 指令集与编程

© 2005 博创科技 北 京 博 创 兴 业 科 技 有 限 公 司BEIJNG UNIVERSAL PIONEERING TECHNOLOGY Co . , LTD

博创科技 嵌入互动

6 单数据访存指令

Page 74: ARM 指令集与编程

博创科技 嵌入互动

© 2005 博创科技

6 单数据访存指令 第一类:

读写字 : ldr / str 读写无符号字节 : ldrb / strb

第二类: 读写无符号半字: ldrh / strh 读有符号半字: ldrsh 读有符号字节: ldrsb

Page 75: ARM 指令集与编程

博创科技 嵌入互动

© 2005 博创科技

6.1 第一类指令的指令格式

0 0 0 0 0 0 0 0 0 0 Rm

03411方式 2 : Rm例子: ldr r0, [r1, +r2]

011

#immed_12方式 1 : #immed_12 (取值范围 0 – 0xfff )例子: ldr r0, [r1, #+0xfff]

shift Rm

03411

#immed_5

67方式 3 : Rm LSL #immed_5 (取值范围 0-31 )例子: ldr r0, [r1, r2 LSL #31] 0

5

0/1 : str/ldr

0/1 : 无 / 有 (!)0/1 : 后变址 / 前变址

0/1 : 字 / 无符号字节

cond Rn Rd 第 2 操作数07811121516192022

01

272831 2324

U B W L

2126

PI

25

0/1 : 加 /减 ( 第 2 操作数 )

0/1 : 立即数 ( 方式 1)/ 寄存器 ( 方式 2,3)

Page 76: ARM 指令集与编程

博创科技 嵌入互动

© 2005 博创科技

6.2 第一类指令的语法 语法

ldr|str{<cond>}{b} <Rd>, [<Rn>, #+<immed_12]{!} ldr|str{<cond>}{b} <Rd>, [<Rn>, +<Rm>]{!} ldr|str{<cond>}{b} <Rd>, [<Rn>, +<Rm>, <shift> #<immed_5>]{!} ldr|str{<cond>}{b} <Rd>, [<Rn>], #+<immed_12 ldr|str{<cond>}{b} <Rd>, [<Rn>], +<Rm> ldr|str{<cond>}{b} <Rd>, [<Rn>], +<Rm>, <shift> #<immed_5>

举例 ldrb r0, [r1, #+0xfff] /* 把 r1+0xfff 地址的字节读入 r0 */ ldr r0, [r1, +r2]! /*把 r1+r2 地址的 32 比特数读入 r0 ,然后 r1= r1+r2 */ str r0, [r1, +r2, LSL #31] /* 把 r0 ( 32bit )写到地址 r1+(r2<<31) */ ldr r0, [r1], #+0xfff /* 把 r1 地址的数读入 r0 ,然后 r1=r1+0xfff */ ldr r0, [r1], +r2 /* 把 r1 地址的数读入 r0 ,然后 r1=r1+r2 */ ldr r0, [r1], +r2, LSL #31 /* 把 r1 地址的数读入 r0 ,然后 r1=r1+(r2<<31) */

Page 77: ARM 指令集与编程

博创科技 嵌入互动

© 2005 博创科技

6.2 第一类指令说明 说明

ldr / str 读 / 写一个 32bit 字到 / 从一个 32bit 的寄存器,要求读 / 写地址字对齐。 ldrb :读一个 8bit 字节到一个 32bit 的寄存器,不要求地址对齐,寄存器的高 24 位清零。 strb :将寄存器的低 8 位,写入内存的某个地址。不要求地址对齐。

Page 78: ARM 指令集与编程

博创科技 嵌入互动

© 2005 博创科技

6.3 第二类指令 语法

同第一类指令 说明

ldrh :读取 16bit半字到一个 32bit 寄存器,要求地址半字对齐,目标寄存的高 16bit 清零。 strh :将寄存器的低 16bit 存放到内存中,要求地址半字对齐。 ldrsh :将内存中的一个 16bit半字读到一个 32bit 寄存器中,要求地址半字对齐。寄存器高 16bit根据符号位扩展。 ldrsb :将内存中的一个 8bit 字节读到一个 32bit 寄存器中,寄存器高 24bit根据符号位扩展。不要求地址对齐。

Page 79: ARM 指令集与编程

博创科技 嵌入互动

© 2005 博创科技

6.4 前 / 后变址

0 0 0 0 0 0 0 0 0 0 Rm

03411方式 2 : Rm例子: ldr r0, [r1, +r2]

011

#immed_12方式 1 : #immed_12 (取值范围 0 – 0xfff )例子: ldr r0, [r1, #+0xfff]

shift Rm

03411

#immed_5

67方式 3 : Rm LSL #immed_5 (取值范围 0-31 )例子: ldr r0, [r1, r2 LSL #31] 0

5

0/1 : str/ldr

0/1 : 无 / 有 (!)0/1 : 后变址 / 前变址

0/1 : 字 / 无符号字节

cond Rn Rd 第 2 操作数07811121516192022

01

272831 2324

U B W L

2126

PI

25

0/1 : 加 /减 ( 第 2 操作数 )

0/1 : 立即数 ( 方式 1)/ 寄存器 ( 方式 2,3)

Page 80: ARM 指令集与编程

博创科技 嵌入互动

© 2005 博创科技

6.4.1 简单的基址寻址 基址寄存器数据访问

str r0, [r1] ldr r2, [r1]

Page 81: ARM 指令集与编程

博创科技 嵌入互动

© 2005 博创科技

6.4.2 前变址寻址 str r0,[r1,#12] ; /* {! } mem32[r1+12] = r0 r1 = r1 ; /*{r1 = r1 + 12;}

Page 82: ARM 指令集与编程

博创科技 嵌入互动

© 2005 博创科技

6.4.3 后变址寻址数据访问 str r0, [r1], #12 mem32[r1] = r0; r1 = r1 + 12;

Page 83: ARM 指令集与编程

博创科技 嵌入互动

© 2005 博创科技

6.5 三种寻址方式 ( 第一类 )

0 0 0 0 0 0 0 0 0 0 Rm

03411方式 2 : Rm例子: ldr r0, [r1, +r2]

011

#immed_12方式 1 : #immed_12 (取值范围 0 – 0xfff )例子: ldr r0, [r1, #+0xfff]

shift Rm

03411

#immed_5

67方式 3 : Rm LSL #immed_5 (取值范围 0-31 )例子: ldr r0, [r1, r2 LSL #31] 0

5

0/1 : str/ldr

0/1 : 无 / 有 (!)0/1 : 后变址 / 前变址

0/1 : 字 / 无符号字节

cond Rn Rd 第 2 操作数07811121516192022

01

272831 2324

U B W L

2126

PI

25

0/1 : 加 /减 ( 第 2 操作数 )

0/1 : 立即数 ( 方式 1)/ 寄存器 ( 方式 2,3)

Page 84: ARM 指令集与编程

博创科技 嵌入互动

© 2005 博创科技

6.5 寻址方式 1— 立即数变址寻址 ldr|str{<cond>}{b} <Rd>, [<Rn>, #+<immed_12]{!} ldr|str{<cond>}{b} <Rd>, [<Rn>], #+<immed_12 说明:

无叹号的前变址,当 pc 作为 Rn 时,内存基地址为当前指令地址加 8 字节偏移 ; 后变址或有叹号的前变址,当 pc 作为 Rn 时,会产生不可预知的结果 在 ADS1.2 中,提示错误 Error : A1324E Undefined effect (PC + writeback) 在 arm-elf-gcc-2.95.3 中,没有提示

后变址或有叹号的前变址,如果 Rn 和 Rd 是同一个寄存器,编译出错 在 ADS1.2 中,提示错误 Error : A1325E: Undefined effect (destination same as

written-back base) 在 arm-elf-gcc-2.95.3 中,提示 Warning: destination register same as write-bac

k base 如果 immed_12超过 0xfff ,编译会出错

在 ADS1.2 中,提示错误 Error : A1174E: Data transfer offset out of range 在 arm-elf-gcc-2.95.3 中,提示 Error: address offset too large

Page 85: ARM 指令集与编程

博创科技 嵌入互动

© 2005 博创科技

6.5 寻址方式 2— 寄存器变址寻址 ldr|str{<cond>}{B} <Rd>, [<Rn>, +<Rm>]{!} ldr|str{<cond>}{B} <Rd>, [<Rn>], +<Rm> 说明:

无论如何, pc 都不能作 Rm 。 无叹号的前变址,当 pc 作为 Rn 时,内存基地址为当前指令地址加 8 字节偏移;后变址或有叹号的前变址,当 pc 作为 Rn 时,会产生不可预知的结果。 后变址或有叹号的前变址,如果 Rn 和 Rd 是同一个寄存器,会出现不可预知的结果。

Page 86: ARM 指令集与编程

博创科技 嵌入互动

© 2005 博创科技

6.5 寻址方式 3- 寄存器移位变址寻址 ldr|str{<cond>}{B} <Rd>, [<Rn>, +<Rm>, <shift> #<immed_5>]{!} ldr|str{<cond>}{B} <Rd>, [<Rn>], +<Rm>, <shift> #<immed_5> 说明:

无论如何, pc 都不能作 Rm 。 无叹号的前变址,当 pc 作为 Rn 时,内存基地址为当前指令地址加 8 字节偏移;后变址或有叹号的前变址,当 pc 作为 Rn 时,会产生不可预知的结果。 后变址或有叹号的前变址,如果 Rn 和 Rd 是同一个寄存器,会出现不可预知的结果。 如果 immed_5超过 31 ,编译器报错。

Page 87: ARM 指令集与编程

博创科技 嵌入互动

© 2005 博创科技

目录1. 总体介绍:指令分类,特点,格式,条件码2. ARM 指令寻址方式3. 数据处理指令:数据传输指令,算术指令,逻辑指令,比较指令,乘法指令 ( 略 ) ,前导零计数 ( 略 )4. 程序状态访问指令5. 跳转指令6. 单数据访存指令7. 多数据访存指令8. 其它指令:信号量操作指令,异常中断产生指令,协处理器指令

( 略 )9. 伪指令10. 基于 ARM 的编程

Page 88: ARM 指令集与编程

© 2005 博创科技 北 京 博 创 兴 业 科 技 有 限 公 司BEIJNG UNIVERSAL PIONEERING TECHNOLOGY Co . , LTD

博创科技 嵌入互动

7 多数据访存指令

Page 89: ARM 指令集与编程

博创科技 嵌入互动

© 2005 博创科技

7 多数据访存指令 批量访存指令可以实现一组( 1-16 )寄存器和一块( 4-64 字节)连续内存单元之间的数据传输。

Page 90: ARM 指令集与编程

博创科技 嵌入互动

© 2005 博创科技

7.1 指令格式

Page 91: ARM 指令集与编程

博创科技 嵌入互动

© 2005 博创科技

7.2 ldm/stm 指令的语法 语法

ldm|stm{<cond>}<addressing_mode> <Rn>{!}, <registers>{^} <addressing_mode> 有 4 种:

IA (Increment After) 事后递增 IB (Increment Before) 事先递增 DA (Decrement After) 事后递减 DB (Decrement Before) 事先递减

例子 ldmia r0, {r5-r8}/* 将内存中 (r0)到 (r0+12)4 个字读取到 r5~r8 的 4 个寄存器中 */ ldmib r0, {r5-r8}/* 将内存中 (r0+4)到 (r0+16)4 个字读取到 r5~r8 的 4 个寄存器中 */ ldmda r0, {r5-r8}/* 将内存中 (r0-12)到 (r0)4 个字读取到 r5~r8 的 4 个寄存器中 */ ldmdb r0, {r5-r8}/* 将内存中 (r0-16)到 (r0)4 个字读取到 r5~r8 的 4 个寄存器中 */

Page 92: ARM 指令集与编程

博创科技 嵌入互动

© 2005 博创科技

7.2 ldm/stm 指令的语法 ( 续 )

说明 递增方式和递减方式处理寄存器列表和内存地址对应关系时采用不同的顺序,见前面的例子。可以总结为:编号低的寄存器对应低内存地址。 pc 不能作为 stm 指令的 <Rn> ,否则结果不可预知。 感叹号“!”表示执行后将更新 <Rn> 。 “^” 不能在 usr 和 system模式下使用,否则结果不可预知。在其它模式下使用时,含义和寄存器列表是否包含 pc 有关,见后面的详述。

Page 93: ARM 指令集与编程

博创科技 嵌入互动

© 2005 博创科技

7.3 ldm 指令的三种用法编号 ! ^ pc ldm 指令不同的功能 用法1 是 是 是 同 (5) ,但是更新 <Rn> 3

2 是 是 否 编译警告 (ADS1.2) : Warning : A1329W: Unsafe instruction (forced user mode xfer with write-back to base)

2

3 是 否 是 同 (7) ,但是更新 <Rn> 1

4 是 否 否 同 (8) ,但是更新 <Rn> ,且 <Rn> 不能出现在 <registers> 中 1

5 否 是 是 数据读取的同时,拷贝 spsr到 cpsr 3

6 否 是 否 <registers>采用 user模态下的寄存器 2

7 否 否 是 同 (8) ,可用于程序跳转。 1

8 否 否 否 正常读取 1

Page 94: ARM 指令集与编程

博创科技 嵌入互动

© 2005 博创科技

7.4 stm 指令的两种用法编号 ! ^ ldm 指令不同的功能 用法1 是 是 同 (3) ,但是更新 <Rn> 2

2 是 否 同 (4) ,但是更新 <Rn> 。当 <Rn> 是 <registers> 中编号最小的寄存器时,指令将 <Rn>的初值保存;否则结果不可预测。 1

3 否 是 <registers>采用 user模态下的寄存器 2

4 否 否 正常写入 1

Page 95: ARM 指令集与编程

博创科技 嵌入互动

© 2005 博创科技

7.5 多数据访存的程序例子/* r12 指向源数据起点 *//* r14 指向源数据终点 *//* r13 指向目标地址 */

loop:ldmia r12!, {r0-r11} /* 读 48 字节 */stmia r13!, {r0-r11} /* 写 48 字节 */cmp r12, r14 /* 是否到末尾 */bne loop /* 重复循环 */

Page 96: ARM 指令集与编程

博创科技 嵌入互动

© 2005 博创科技

7.6 模拟栈 ARM 指令集中没有用于栈的操作指令,但是可以用多数据访存指令来模拟。

Page 97: ARM 指令集与编程

博创科技 嵌入互动

© 2005 博创科技

7.6.1 栈的分类 栈的分类(按指针) :

栈指针指向最后一个被占用的地址 (Full Stack) 在 push 前需要先将栈指针减小

栈指针指向下一个被占用的地址 (Empty Stack) 在 push 之后需要将栈指针减小

栈的分类(按方向): 上升的栈( Ascending Stack )

向高地址扩展 下降的栈( Descending Stack )

向低地址扩展

Page 98: ARM 指令集与编程

博创科技 嵌入互动

© 2005 博创科技

7.6.2 模拟压栈操作

块数据访问指令 栈访问指令 说明stmda stmed 下降型空栈stmia stmea 上升型空栈stmdb stmfd 下降型满栈stmib stmfa 上升型满栈

Page 99: ARM 指令集与编程

博创科技 嵌入互动

© 2005 博创科技

7.6.3 模拟退栈操作

块数据访问指令 栈访问指令 说明ldmda ldmfa 上升型满栈ldmia ldmfd 下降型满栈ldmdb ldmea 上升型空栈ldmib ldmed 下降型空栈

Page 100: ARM 指令集与编程

博创科技 嵌入互动

© 2005 博创科技

7.6.4 模拟栈操作 模拟 stack 的访问

stmfd / ldmfd : Full Descending Stack stmfa / ldmfa : Full Ascending Stack. stmed / ldmed : Empty Descending Stack stmea / ldmea : Empty Ascending Stack

常见的情况 stmfd sp!, {r0-r12, lr} // 保存所有有寄存器(包括返回地址)

…… ldmfd sp!, {r0-r12, pc} // 恢复所有寄存器(包括 pc )

Page 101: ARM 指令集与编程

博创科技 嵌入互动

© 2005 博创科技

7.6.5 栈操作图示

Page 102: ARM 指令集与编程

博创科技 嵌入互动

© 2005 博创科技

目录1. 总体介绍:指令分类,特点,格式,条件码2. ARM 指令寻址方式3. 数据处理指令:数据传输指令,算术指令,逻辑指令,比较指令,乘法指令 ( 略 ) ,前导零计数 ( 略 )4. 程序状态访问指令5. 跳转指令6. 单数据访存指令7. 多数据访存指令8. 其它指令:信号量操作指令,异常中断产生指令,协处理器指令

( 略 )9. 伪指令10. 基于 ARM 的编程

Page 103: ARM 指令集与编程

© 2005 博创科技 北 京 博 创 兴 业 科 技 有 限 公 司BEIJNG UNIVERSAL PIONEERING TECHNOLOGY Co . , LTD

博创科技 嵌入互动

8 其它指令

Page 104: ARM 指令集与编程

博创科技 嵌入互动

© 2005 博创科技

8 其它指令 信号量操作指令:用于进程间的同步互斥,提供对信号量的原子操作。 异常中断产生指令:用于系统调用和调试。

Page 105: ARM 指令集与编程

博创科技 嵌入互动

© 2005 博创科技

8.1 信号量操作指令 语法

swp|swpb{<cond>} <Rd>, <Rm>, [<Rn>] 例子

swp r1, r2, [r3] /* 将内存单元 (r3) 中的字读取到 r1 ,同时将 r2 中的数据写入内存单元 (r3) 中 */ swp r1, r1, [r2] /* 将 r1 寄存器内容和内存单元 (r2) 的内容互换 */

说明 swpb读取 8bit 数据到寄存器后会对高 24 位清零,写到内存的 8bit 数来自寄存器低 8 位

Page 106: ARM 指令集与编程

博创科技 嵌入互动

© 2005 博创科技

8.1 信号量操作指令 ( 续 )

Page 107: ARM 指令集与编程

博创科技 嵌入互动

© 2005 博创科技

8.2 异常产生指令 指令格式

语法 swi{<cond>} <immed_24>

说明 主要用于用户程序调用操作系统的 API 。参数传递通常有两种方法: 指令中的 24bit 立即数指定 API 号,参数通过寄存器传递。 忽略指令中的 24bit 立即数, r0 指定 API 号,其它参数通过其它寄存器传递。

cond Immed_24

023

1 1 1 1

272831 24

Page 108: ARM 指令集与编程

博创科技 嵌入互动

© 2005 博创科技

8.3 中断产生指令 语法

bkpt <immed_16> 说明

用于产生软件断点中断。 主要用于调试。 ARMv5及以上版本支持。

Page 109: ARM 指令集与编程

博创科技 嵌入互动

© 2005 博创科技

目录1. 总体介绍:指令分类,特点,格式,条件码2. ARM 指令寻址方式3. 数据处理指令:数据传输指令,算术指令,逻辑指令,比较指令,乘法指令 ( 略 ) ,前导零计数 ( 略 )4. 程序状态访问指令5. 跳转指令6. 单数据访存指令7. 多数据访存指令8. 其它指令:信号量操作指令,异常中断产生指令,协处理器指令

( 略 )9. 伪指令10. 基于 ARM 的编程

Page 110: ARM 指令集与编程

© 2005 博创科技 北 京 博 创 兴 业 科 技 有 限 公 司BEIJNG UNIVERSAL PIONEERING TECHNOLOGY Co . , LTD

博创科技 嵌入互动

9 伪指令

Page 111: ARM 指令集与编程

博创科技 嵌入互动

© 2005 博创科技

Page 112: ARM 指令集与编程

博创科技 嵌入互动

© 2005 博创科技

9 伪指令 在 ARM汇编语言源程序中有些特殊助记符,它们没有相对应的操作码或者机器码,通常称为伪指令,它们所完成的操作称为伪操作。伪指令在源程序中的作用是为完成汇编程序作各种准备工作的,由汇编程序在源程序的汇编期间进行处理,仅在汇编过程中起作用。 符号定义伪指令 数据定义伪指令 汇编控制伪指令 信息报告伪指令 宏指令以及其他伪指令。

Page 113: ARM 指令集与编程

博创科技 嵌入互动

© 2005 博创科技

符号定义伪指令Ⅰ 用于定义 ARM汇编程序中的变量、对变量赋值以及定义寄存器的别名等。 用于定义局部变量的 LCLA、 LCLL、 LCLS; 用于定义全局变量的 GBLA、GBLL、GBLS ; 用于对变量赋值的 SETA、SETL、 SETS ; 为通用寄存器列表定义名称的 RLIST。

Page 114: ARM 指令集与编程

博创科技 嵌入互动

© 2005 博创科技

符号定义伪指令Ⅱ 1. LCLA、 LCLL、 LCLS 格式: LCLA/LCLL/LCLS 局部变量名 说明: LCLA、 LCLL、 LCLS伪指令用于定义一个汇编程序中的局部变量,并初始化,其中: LCLA 定义一个局部的数字变量,初始化为 0 ; LCLL 定义一个局部的逻辑变量,初始化为 F; LCLS定义一个局部的字符串变量,初始化为空串;

这三条伪指令用于声明局部变量,在其局部作用范围内变量名必须唯一。

Page 115: ARM 指令集与编程

博创科技 嵌入互动

© 2005 博创科技

符号定义伪指令Ⅲ 2.  GBLA、 GBLL、 GBLS 格式: GBLA/GBLL/GBLS 变量名 说明: GBLA、 GBLL、 GBLS伪操作定义一个汇编程序中的全局变量,并初始化,其中: GBLA 定义一个全局数字变量,并初始化为 0 ; GBLL 定义一个全局逻辑变量,并初始化为“ F”; GBLS定义一个全局字符串变量,并初始化为空串;

这三条伪指令用于定义全局变量,因此在整个程序范围内变量名必须唯一。

Page 116: ARM 指令集与编程

博创科技 嵌入互动

© 2005 博创科技

符号定义伪指令Ⅳ 3. SETA、 SETL、 SETS 格式:变量名 SETA/SETL/SETS 表达式 说明: SETA :给一个数字变量赋值; SETL :给一个逻辑变量赋值; SETS:给一个字符串变Ⅳ量赋值;

格式中的变量名必须为已经定义过的全局或局部变量,表达式为将要赋给变量的值。

Page 117: ARM 指令集与编程

博创科技 嵌入互动

© 2005 博创科技

符号定义伪指令Ⅴ4. RLIST 格式:名称 RLIST {寄存器列表 } 说明: RLIST可用于对一个通用寄存器列表定义名称,该名称可在 ARM指令 LDM/STM 中使用。在 LDM/STM 指令中,列表中的寄存器为根据寄存器的编号由低到高访问次序,与列表中的寄存器排列次序无关。

Page 118: ARM 指令集与编程

博创科技 嵌入互动

© 2005 博创科技

数据定义伪指令Ⅰ 用于为数据分配存储单元,同时也可完成已分配存储单元的初始化。 DCB DCW/DCWU DCD/DCDU DCQ/DCQU DCFS/DCFSU DCFD/DCFDU SPACE FIELD MAP

Page 119: ARM 指令集与编程

博创科技 嵌入互动

© 2005 博创科技

数据定义伪指令Ⅱ 1.  DCB: 标号 DCB 表达式 说明: DCB用于分配一块字节单元并用伪指令中指定的表达式进行初始化。其中,表达式可以为使用双引号的字符串或 0——255的数字 ,DCB可用“ =”代替。 2.  DCW/DCWU: 标号 DCW/DCWU 表达式 说明: DCW分配一段半字存储单元并用表达式值初始化,它定义的存储空间是半字对齐的。

Page 120: ARM 指令集与编程

博创科技 嵌入互动

© 2005 博创科技

数据定义伪指令Ⅲ 3.  DCD/DCDU : 标号 DCD/DCDU 表达式 说明: DCD 伪指令用于分配一块字存储单元并用伪指令中指定的表达式初始化,它定义的存储空间是字对齐的。 DCD也可用“ &”代替。 4.  DCQ/DCQU : 标号 DCQ/DCQU 表达式 说明: DCQ用于分配一块以 8个字节为单位的存储区域并用伪指令中指定的表达式初始化,它定义的存储空间是字对齐的。 DCQU功能跟 DCQ类似,只是分配的存储单元不严格字对齐。

Page 121: ARM 指令集与编程

博创科技 嵌入互动

© 2005 博创科技

数据定义伪指令Ⅳ 5. DCFD/DCFDU: 标号 DCFD/DCFDU 表达式 说明: DCFD 用于为双精度的浮点数分配一片连续的字存储单元并用伪指令中指定的表达式初始化,它定义的存储空间是字对齐的,每个双精度的浮点数占据两个字单元。 DCFDU功能跟 DCFD 类似,只是分配的存储单元不严格字对齐。 6.    DCFS/DCFSU: 标号 DCFS/DCFSU 表达式 说明: DCFS用于为单精度的浮点数分配一片连续的字存储单元并用表达式初始化 , 它定义的存储空间是字对齐的 ,每个单精度浮点数使用一个字单元 .DCFSU功能跟 DCFS类似,只是分配的存储单元不严格字对齐。

Page 122: ARM 指令集与编程

博创科技 嵌入互动

© 2005 博创科技

数据定义伪指令Ⅴ 7.  SPACE: 标号 SPACE 表达式 说明: SPACE用于分配一片连续的存储区域并初始化为 0, 表达式为要分配的字节数 ,SPACE 也可用“%”代替。 8.   MAP: MAP 表达式 [ ,基址寄存器 ] 说明: MAP定义一个结构化的内存表的首地址, “^”可以用来代替 MAP。 9.   FILED: 标号 FIELD 字节数 说明: FIELD 用于定义一个结构化内存表中的数据域,“ #” 可用来代替 FILED 。

Page 123: ARM 指令集与编程

博创科技 嵌入互动

© 2005 博创科技

汇编控制伪指令Ⅰ 汇编控制伪操作用于指引汇编程序的执行流程: MACRO、MEND IF 、 ELSE、 ENDIF  WHILE、WEND  MEXIT

Page 124: ARM 指令集与编程

博创科技 嵌入互动

© 2005 博创科技

汇编控制伪指令Ⅱ 1.  MACRO、MEND MACRO [$ 标号 ] 宏名 [$参数 1 , $参数 2 ,…… ] 指令序列 MEND 说明: MACRO 表明一个宏定义的开始, MEND 则表示一个宏的结束,MACRO、MEND 前呼后应可以将一段代码定义为一个整体,又称宏,然后就可以在程序中通过宏的名称及参数调用该段代码。 MACRO和 MEND 之间的代码称为宏定义体,在宏定义体的第一行声明宏的原型,宏的原型包含宏名、所需的参数。在源程序被编译时,汇编器将宏调用展开,用宏定义中的指令序列替换程序中的宏调用,并将实际参数的值传递给宏定义中的参数。注意宏操作可以嵌套使用,并可以在编译时用选项加以控制。

Page 125: ARM 指令集与编程

博创科技 嵌入互动

© 2005 博创科技

汇编控制伪指令Ⅲ 2. IF、 ELSE、 ENDIF IF 逻辑表达式

代码段 1 ELSE

代码段 2 ENDIF 说明: IF 、 ELSE 、 ENDIF伪操作能根据逻辑表达式的成立与否决定是否在编译时加入某个指令序列。 IF 、 ELSE 、 ENDIF可以分别用“ [”、“ |”、“ ]”代替。 IF 、 ELSE 、 ENDIF伪指令可以嵌套使用。

Page 126: ARM 指令集与编程

博创科技 嵌入互动

© 2005 博创科技

汇编控制伪指令Ⅲ 3. WHILE、WEND: WHILE 逻辑表达式

代码段 WEND 说明:WHILE和WEND 伪指令能根据逻辑表达式的成立与否决定是否循环执行这个代码段。WHILE 、WEND 伪指令可以嵌套使用。 4. MEXIT: MEXIT 说明: MEXIT用于从宏中退出。

Page 127: ARM 指令集与编程

博创科技 嵌入互动

© 2005 博创科技

其他伪指令Ⅰ 1. ASSERT: ASSERT 逻辑表达式 说明: ASSERT用来表示程序的编译必须满足一定的条件,如果逻辑表达式不满足,则编译器会报错。 2.  ALIGN: ALIGN [ 表达式 [ ,偏移量 ]] 说明: ALIGN伪操作可以通过填充字节使当前的位置满足一定的对齐方式。其中,表达式的值为 2 的幂,如 1、 2、 4、 8、 16等,用于指定对齐方式。如果伪操作中没有指定表达式,则编译器会将当前位置对齐到下一个字的位置。偏移量也是个数字表达式,如果存在偏移量,则当前位置的自动对齐到: 2 的表达式值次方+偏移量。

Page 128: ARM 指令集与编程

博创科技 嵌入互动

© 2005 博创科技

其他伪指令Ⅱ 3. AREA: AREA 段名 属性,…… 说明: AREA 用于定义一个代码段、数据段或者特定属性的段。如果段名以数字开头,那么该段名需用“ |”字符括起来,如 |7wolf| ,用 C的编译器产生的代码一般也用“ |”括起来。属性部分表示该代码段 / 数据段的相关属性,多个属性可以用“,”分隔。 常见属性如下:•  DATA :定义数据段。•  CODE:定义代码段。• READONLY :表示本段为只读。• READWRITE:表示本段可读写。• ALIGN= 表达式:对齐方式为 2 表达式次方,例如:表达式 =3 ,则对齐方式为8字节对齐。表达式的取值范围为 0——31 。• COMMON属性:定义一个通用段,这个段不包含用户代码和数据。

Page 129: ARM 指令集与编程

博创科技 嵌入互动

© 2005 博创科技

其他伪指令Ⅲ 4.  CODE16、 CODE32: CODE16/CODE32 说明: CODE16伪操作指示编译器后面的代码为 16位的 Thumb 指令。 CODE32 伪操作指示编译器后面的代码为 32 位的 ARM 指令。 5.   ENTRY: ENTRY 说明: ENTRY 用于指定汇编程序的入口。在一个完整的汇编程序中至少要有一个 ENTRY ,程序中也可以有多个,此时,程序的真正入口点可在链接时指定,但在一个源文件里最多只能有一个 ENTRY 或者没有 ENTRY 。

Page 130: ARM 指令集与编程

博创科技 嵌入互动

© 2005 博创科技

其他伪指令Ⅳ 6.  END: END 说明:“ END”告诉编译器已经到了源程序的结尾。 7.  EQU : 名称 EQU 表达式 [ ,类型 ] 说明: EQU用于将程序中的数字常量、标号、基于寄存器的值赋予一个等效的名称,这一点类似于 C语言中的# define ,可用“ *”代替EQU。 如果表达式为 32 位的常量,我们可以指定表达式的数据类型,类型域可以有以下三种: CODE16/CODE32/DATA

Page 131: ARM 指令集与编程

博创科技 嵌入互动

© 2005 博创科技

其他伪指令Ⅴ 8. EXPORT: EXPORT 标号 [,WEAK] 说明: EXPORT 在程序中声明一个全局标号,其他的文件中的代码可以该标号可被引用。用户也可以用 GLOBAL 代替 EXPORT。 [,WEAK] 可选项声明其他文件有同名的标号,则该同名标号优先于该标号被引用。 9.   IMPORT: IMPORT 标号 [ , WEAK] 说明: IMPORT 告诉编译器这个标号要在当前源文件中使用,但标号是在其他的源文件中定义的。不管当前源文件是否使用过该标号,这个标号都会加入到当前源文件的符号表中。 [ ,WEAK] 选项表示如果所有的源文件都没有找到这个标号的定义,编译器也不会提示错误信息。编译器在多数情况下将该标号置为 0 ,如果这个标号被 B或 BL 指令引用,则将 B或BL 指令替换为 NOP操作。

Page 132: ARM 指令集与编程

博创科技 嵌入互动

© 2005 博创科技

其他伪指令Ⅵ 10.  EXTERN: EXTERN 标号 [,WEAK] 说明: EXTERN 告诉编译器所使用的标号要在当前源文件中引用 ,但该标号是在其他的源文件中定义的。与 IMPORT不同的是,如果当前源文件实际上没有引用该标号,该标号就不会被加入到当前文件的符号表中。[ ,WEAK] 选项意义同 IMPORT。 11.  RN: 名称 RN 表达式 说明: RN用于给一个寄存器定义一个别名 , 以便程序员记忆该寄存器的功能。其中,名称为给寄存器定义的别名,表达式为寄存器的编码。

Page 133: ARM 指令集与编程

博创科技 嵌入互动

© 2005 博创科技

其他伪指令Ⅶ 12.   GET/INCLUDE : GET文件名 说明: GET将一个源文件包含到当前的源文件中,并将被包含的源文件在当前位置展开进行汇编处理。 INCLUDE和 GET作用等效的。我们通常这样使用这个伪指令:在某源文件中定义一些宏指令,用 MAP和 FIELD 定义结构化的数据类型,用 EQU定义常量的符号名称,然后用 GET/INCLUDE将这个源文件包含到其他的源文件中。 GET/INCLUDE只能用于包含源文件,包含其他文件则需要使用 INCBIN伪指令。 13.   INCBIN: INCBIN 文件名 说明: INCBIN将一个数据文件或者目标文件包含到当前的源文件中,编译时被包含的文件不作任何变动的存放在当前文件中,编译器从后面开始继续处理。

Page 134: ARM 指令集与编程

博创科技 嵌入互动

© 2005 博创科技

其他伪指令Ⅷ 14.  ROUT: [名称 ] ROUT 说明: ROUT可以给一个局部变量定义作用范围。在程序中未使用该伪指令时,局部变量的作用范围为所在的 AREA ,而使用 ROUT后,局部变量的作为范围为当前 ROUT和下一个 ROUT之间。

Page 135: ARM 指令集与编程

博创科技 嵌入互动

© 2005 博创科技

目录1. 总体介绍:指令分类,特点,格式,条件码2. ARM 指令寻址方式3. 数据处理指令:数据传输指令,算术指令,逻辑指令,比较指令,乘法指令 ( 略 ) ,前导零计数 ( 略 )4. 程序状态访问指令5. 跳转指令6. 单数据访存指令7. 多数据访存指令8. 其它指令:信号量操作指令,异常中断产生指令,协处理器指令

( 略 )9. 伪指令10. 基于 ARM 的编程

Page 136: ARM 指令集与编程

© 2005 博创科技 北 京 博 创 兴 业 科 技 有 限 公 司BEIJNG UNIVERSAL PIONEERING TECHNOLOGY Co . , LTD

博创科技 嵌入互动

9 THUM 指令集

Page 137: ARM 指令集与编程

博创科技 嵌入互动

© 2005 博创科技

2.2. ThumbThumb 指令 寄存器使用指令 寄存器使用1.1.总体介绍:指令分类,特点,条件执行,移位操作总体介绍:指令分类,特点,条件执行,移位操作

3. Thumb模式的进入和退出4.4. 指令分类介绍指令分类介绍

Page 138: ARM 指令集与编程

博创科技 嵌入互动

© 2005 博创科技

指令特点指令特点 1、 16 位的指令子集,代码密度小。 2、在指令集名中,含有 T 的均可执行 Thumb 指令。 3、 CPSR 中的 T 标志位决定是执行 Thumb 指令还是 ARM 指令,如置位,执行

Thumb 指令,否则执行 ARM 指令。 4、 Thumb 状态下没有协处理器指令。 5、所有 Thumb 指令均有对应的 ARM 指令。 6、 Thumb 是一个不完整的体系结构,不能指望处理器只执行 Thumb 代码而不支持 ARM 指令集。

Page 139: ARM 指令集与编程

博创科技 嵌入互动

© 2005 博创科技

条件执行和移位操作条件执行和移位操作

1、在 Thumb 指令 ISA 中,只有分支指令可以被条件执行。 2、由于 16 位的限制,桶形移位操作也变成单独指令。

Page 140: ARM 指令集与编程

博创科技 嵌入互动

© 2005 博创科技

指令分类指令分类 分支指令 数据处理指令 单寄存器读取和存储指令 多寄存器读取和存储指令 移位操作 堆栈指令 软件中断指令

Page 141: ARM 指令集与编程

博创科技 嵌入互动

© 2005 博创科技

ThumbThumb 指令寄存器使用指令寄存器使用 1、只有 R0-R7 可以被任意指令访问 2、 R8-R12 只能通过 MOV、 ADD 和 CMP 访问 3、 R13 ( sp )、 R14 ( lr )、 R15 ( pc )限制访问 4、 cpsr 间接访问 ( CMP 和数据处理指令影响) 5、 spsr 不能访问

Page 142: ARM 指令集与编程

博创科技 嵌入互动

© 2005 博创科技

Thumb模式的进入和退出 • 复位后, ARM 启动并执行 ARM 指令。转向执行 Thumb 指令的通常方法是执行一条交换转移指令 BX 。若 BX 指令指定的寄存器的最低位为

1 ,则将 T 置位,并将程序计数器切换为寄存器其他位给出的地址。 • 异常返回也可以将微处理器从 ARM 状态转换为 Thumb 状态。通常这种指令用于返回到进入异常前所执行的指令流,而不是特地用于转换到 T

humb模式。 • 执行 Thumb BX 指令可以显式地返回到 ARM 指令流。

Page 143: ARM 指令集与编程

博创科技 嵌入互动

© 2005 博创科技

• B{L}X Rm • 目标为 ARM 代码或 Thumb 代码

Page 144: ARM 指令集与编程

博创科技 嵌入互动

© 2005 博创科技

.ARM ADR r0 , ThumbProg+1 BX r0 /* 跳到 ThumbProg ,程序切换到 Thumb 状志 */ .THUMB /*THUMB 指示编译器后面的为 Thumb 指令 CODE16*/ ThumbProg: ... ADR r0 , ARMProg BX r0 /* 跳转到 ARMProg ,程序切换到 ARM 状态 */ .ARM /*.ARM 指示编译器后面的为 ARM 指令 */ ARMProg: MOV r4 , #4

Page 145: ARM 指令集与编程

博创科技 嵌入互动

© 2005 博创科技

分支指令 分支指令用于:

向后转移形成循环; 条件结构向前转移; 转向子程序; 处理器从 Thumb 状态切换到 ARM 状态。

程序相对转移,特别是条件转移与在 ARM 状态下相比,在范围上有更多的限制,转向子程序只能是无条件转移。

Page 146: ARM 指令集与编程

博创科技 嵌入互动

© 2005 博创科技

B 指令。 格式 1 : B < 条件码 > <Label> 编码结构: -254~+254

格式 2 : B <Label>编码结构: ±2KB

15 12 01 1 0 1

11 8条 件 码 8位 偏 移 量

7

15 11 01 1 1 0 0

1011位 偏 移 量

Page 147: ARM 指令集与编程

博创科技 嵌入互动

© 2005 博创科技

BL、 BLX 指令 ±4M 格式: BL{X} <Label>

15 11 01 1 1 1

1011位 偏 移 量

12H

Why ±4M±4M ?BL 指令实际上分为两条指令,一条指令 H=0 ,它把 11位偏移量左移 12 位,加上现行 PC ,写入 R14 ( LR )中,另一条指令 H=1 ,它把 LR 加上 11 位偏移量乘 2 写入 PC ,同时把下一条指令的地址写入 R14 中。

Page 148: ARM 指令集与编程

博创科技 嵌入互动

© 2005 博创科技

BX、 BLX 指令 格式: B{L}X Rm 字节码结构:

15 0 0 1 0 0 0 1 1 1

80 0 0

3Rm

5 267L H

其中: Rm 装有目的地址的 ARM 寄存器, m=0~15 。 Rm 的位 [0] 不用于地址部分。若 Rm 的位 [0] 清零,则— 位 [1]也必须清零;— 指令清零 CPSR 中的标志 T ,目的地址的代码被解释为 ARM 代码。

Page 149: ARM 指令集与编程

博创科技 嵌入互动

© 2005 博创科技

堆栈指令 功能:低寄存器和可选的 LR 进栈。低寄存器和可选的 PC 出栈。 格式: POP { <Reglist> { , PC}} PUSH { <Reglist> { , LR}} 其中: Reglist 低寄存器或低寄存器范围的、用逗号隔开的列表。 注释: 1 . Thumb 堆栈是满递减堆栈,向下增长,且 SP 指向堆栈的最后入口。 2 .寄存器以数字顺序存储在堆栈中。最低数字的寄存器其地址最低。 3 . POP {reglist,PC} 这条指令引起处理器转移到从堆栈弹出给 PC 的地址。这通常是从子程序返回,其中 LR 在子程序开头压进堆栈。

Page 150: ARM 指令集与编程

博创科技 嵌入互动

© 2005 博创科技

对于 ARMv5T及以上版本,则 若读取到 PC 中值的位 [1:0] 是 b00 ,则处理器变换到 ARM 状态;位 [1:0] 不允许有值 b10 。 条件码标志 这些指令不影响条件码标志 例 : PUSH {R0,R4-R7} ; R0、 R4~R7 进栈 PUSH {R0,LR} POP {R2,R5} POP {R0-R7,PC} ;出栈并从子程序返回

Page 151: ARM 指令集与编程

博创科技 嵌入互动

© 2005 博创科技

单寄存器读取和存储指令

Thumb 单寄存器传送类指令是 ARM 单寄存器传送类指令的一个子集,和ARM 有相同的指令格式。

多寄存器读取和存储指令 Thumb 多寄存器传送类指令和 ARM 有相同的指令格式。

Page 152: ARM 指令集与编程

博创科技 嵌入互动

© 2005 博创科技

移位操作 ASR、 LSL、 LSR 和 ROR 运算 功能:移位和循环移位操作。这些指令可使用寄存器中的值或立即数移位。 格式 1 : < 操作码 > Rd , Rn , < #immed_5>

15 0 0 0 0

6#5位立即数

51013 11Op

3 2Rn Rd

Page 153: ARM 指令集与编程

博创科技 嵌入互动

© 2005 博创科技

Rd 立即数移位的目的寄存器。 Rd 必须在 R0~R7范围内。 Rn 立即数移位的源寄存器。 Rn 必须在 R0~R7范围内。 immed_5立即数移位量。它是一个取值(在汇编时)为整数的表达式。整数的范围如下: — < 操作码 > 若是 LSL、 ROR ,则为 0~31 ; — 其余则为 1~32 。

Page 154: ARM 指令集与编程

博创科技 嵌入互动

© 2005 博创科技

格式 2 : < 操作码 > Rd | Rn , Rs | Rm 字节码结构:

其中: < 操作码 >同格式 1 。Rd 寄存器控制移位的源寄存器。 Rd 必须在 R0~R7范围内。Rs 在寄存器控制移位中包含移位量的寄存器。 Rs 必须在 R0~R7范围内

15 0 0 1 0 0 0 0 Rd/ Rn

3Rm/ Rs

5 269Op

10

Page 155: ARM 指令集与编程

博创科技 嵌入互动

© 2005 博创科技

数据处理指令 除移位操作之外的数据处理指令,和 ARM 类似。

Page 156: ARM 指令集与编程

博创科技 嵌入互动

© 2005 博创科技

Page 157: ARM 指令集与编程

博创科技 嵌入互动

© 2005 博创科技

TEST1 寄存器相加举例

Page 158: ARM 指令集与编程

博创科技 嵌入互动

© 2005 博创科技

TEST1实验程序

Page 159: ARM 指令集与编程

博创科技 嵌入互动

© 2005 博创科技

第 1、 2、 3 “行为程序说明,使用 ;” “进行注释, ;” 号后面至行结束均为注释内容; 第 4 行声明一个代码段。 ARM 汇编程序至少要声明一个代码段;

TEST1实验说明

Page 160: ARM 指令集与编程

博创科技 嵌入互动

© 2005 博创科技

第 5 行标识程序入口,在仿真调试时会从指定入口处开始运行程序; 第 6 行声明 32 位 ARM 指令, ARM7TDMI(-S) 复位后是 ARM 状态;

TEST1实验说明

Page 161: ARM 指令集与编程

博创科技 嵌入互动

© 2005 博创科技

第 7 ~14 行为实际代码。 标号要顶格书写 ( 如 START、 LOOP 、 ADD_SUB) ,而指令不能顶格书写。 BL 为调用子程序指令,它会把返回地址 ( 即下一条指令的地址 ) 存到

LR ,然后跳转到子程序 ADD_SUB 。 子程序 ADD_SUB 处理结束后将 LR 的值装入 PC 即可返回;

TEST1实验说明

Page 162: ARM 指令集与编程

博创科技 嵌入互动

© 2005 博创科技

第 11~15 行为空行,目的在于增强程序的可读性; 第 16 行用于指示汇编源文件结束。第一个 ARM 汇编程序均要用 END 声明结束

TEST1实验说明

Page 163: ARM 指令集与编程

博创科技 嵌入互动

© 2005 博创科技

TEST1实验步骤 启动 ADS1.2 ,使用 ARM Executable Image工程模板建立一个工程 T

EST1 。 建立汇编源文件 TEST1.S ,编写实验程序,然后添加到工程中。 编译连接工程 (选择make 项 ) 。 选择 [Project]->[Debug] ,启动 AXD 进行软件仿真调试。

Page 164: ARM 指令集与编程

博创科技 嵌入互动

© 2005 博创科技

TEST1实验要求 观察 R0、 R1 运行程序前先打开 Registers 窗口,并设置 R0 的显示格式 Format 为 Decimal 。使用单步运行程序运行。每调用一次 ADD_SUB 子程序后, R0 的值将会加 10 。 观察 R14( 即 LR) 在进入 ADD_SUB 子程序后 R14 寄存器值为 0x0000800C ?。

Page 165: ARM 指令集与编程

博创科技 嵌入互动

© 2005 博创科技

TEST2 内存访问举例

Page 166: ARM 指令集与编程

博创科技 嵌入互动

© 2005 博创科技

TEST2实验程序

Page 167: ARM 指令集与编程

博创科技 嵌入互动

© 2005 博创科技

程序实现:对变量 NumCount 地址中的数据进行加 1 操作。 LDR/STR 指令用于对内存变量的访问、内存缓冲区数据的访问、查表、外围部件的控制操作等等; 若使用 LDR 指令加载数据到 PC 寄存器,则实现程序跳转功能,这样也就实现了程序散转。

TEST2实验说明

Page 168: ARM 指令集与编程

博创科技 嵌入互动

© 2005 博创科技

程序中先使用 EQU 定义 NumCount 为 0x40003000 ; 使用 LDR R0, =NumCount 伪指令将 NumCount 的 32 位地址值装入 R0 ; 然后再使用 LDR 指令加载数据; 加 1 操作后,使用 STR 指令进行存储。

TEST2实验说明

Page 169: ARM 指令集与编程

博创科技 嵌入互动

© 2005 博创科技

读者可更改变量地址。 程序中 B HALT 为死循环, 也可使用 B . 来实现死循环。

TEST2实验说明

Page 170: ARM 指令集与编程

博创科技 嵌入互动

© 2005 博创科技

TEST2实验步骤 启动 ADS1.2 ,使用 ARM Executable Image工程模板建立一个工程

TEST2 。 建立汇编源文件 TEST2.S ,编写实验程序,然后添加到工程中。 编译连接工程 (选择make 项 ) 。 选择 [Project]->[Debug] ,启动 AXD 进行软件仿真调试。

Page 171: ARM 指令集与编程

博创科技 嵌入互动

© 2005 博创科技

TEST2实验要求 观察:设置的地址 0x40003000 中的内容 实现: 运行程序前先打开Memory 窗口,设置观察地址为 0x40003000 ,显示方式 Size 为 32Bit 。 还可以更改该地址上的内容为 0 ,以得到更直观的结果使用单步运行程序。

Page 172: ARM 指令集与编程

博创科技 嵌入互动

© 2005 博创科技

TEST3整数乘方举例

Page 173: ARM 指令集与编程

博创科技 嵌入互动

© 2005 博创科技

TEST3实验程序

Page 174: ARM 指令集与编程

博创科技 嵌入互动

© 2005 博创科技

Page 175: ARM 指令集与编程

博创科技 嵌入互动

© 2005 博创科技

使用 LDM/STM 进行现场寄存器保护,常在子程序中或异常处理中使用。 使用满递减堆栈 (STMFD、 LDMFD 指令 ) SP 进行现场保护,所以设置堆栈指针 SP 时要特别注意。

TEST3实验说明

Page 176: ARM 指令集与编程

博创科技 嵌入互动

© 2005 博创科技

先将 X 的值装入 R0 和 R1 ,使用 R2 进行计数,循环 n-1次 R0=R0*R1 ,运算结果就保存在 R0 中。

若 n=0 ,则运算结果直接赋值 1 ; 若 n=1 ,则运算结果直接赋值 X 。

TEST3实验说明

Page 177: ARM 指令集与编程

博创科技 嵌入互动

© 2005 博创科技

TEST3实验步骤 启动 ADS1.2 ,使用 ARM Executable Image工程模板建立一个工程

Instruction3 。 建立汇编源文件 TEST.S ,编写实验程序,然后添加到工程中。 设置工程连接地址 RO Base 为 0x40000000 , RW Base 为 0x4000300

0 ,设置调试入口地址 Image entry point 为 0x40000000 。

Page 178: ARM 指令集与编程

博创科技 嵌入互动

© 2005 博创科技

TEST3实验步骤 编译连接工程 (选择make 项 ) ,选择 [Project]->[Debug] ,启动 AX

D 进行软件仿真调试。 打开寄存器窗口 (Process Register) ,选择 Current 项监控寄存器 R0、

R1、 R13(SP) 和 R14(LR) 的值。

Page 179: ARM 指令集与编程

博创科技 嵌入互动

© 2005 博创科技

TEST3实验步骤 打开存储器观察口 (Memory) ,设置观察地址为 0x40003EA0 ,显示方式 Size 为 32bit ,监视从 0x40003F00起始的满递减堆栈区。 单步运行,观察寄存器的变化和堆栈区的数据变化。

Page 180: ARM 指令集与编程

博创科技 嵌入互动

© 2005 博创科技

TEST3实验结果

Page 181: ARM 指令集与编程

博创科技 嵌入互动

© 2005 博创科技

Page 182: ARM 指令集与编程

博创科技 嵌入互动

© 2005 博创科技

Page 183: ARM 指令集与编程

博创科技 嵌入互动

© 2005 博创科技

Page 184: ARM 指令集与编程

博创科技 嵌入互动

© 2005 博创科技

目录1. 总体介绍:指令分类,特点,格式,条件码2. ARM 指令寻址方式3. 数据处理指令:数据传输指令,算术指令,逻辑指令,比较指令,乘法指令 ( 略 ) ,前导零计数 ( 略 )4. 程序状态访问指令5. 跳转指令6. 单数据访存指令7. 多数据访存指令8. 其它指令:信号量操作指令,异常中断产生指令,协处理器指令

( 略 )9. 伪指令10. 基于 ARM 的编程

Page 185: ARM 指令集与编程

© 2005 博创科技 北 京 博 创 兴 业 科 技 有 限 公 司BEIJNG UNIVERSAL PIONEERING TECHNOLOGY Co . , LTD

博创科技 嵌入互动

10 基于 ARM 的编程

Page 186: ARM 指令集与编程

博创科技 嵌入互动

© 2005 博创科技

编程工具 编程语言10 基于 ARM 的编程

Page 187: ARM 指令集与编程

博创科技 嵌入互动

© 2005 博创科技

10.1 编程工具 直接面向硬件的开发

SDT、 ADS (集成开发环境) CodeWorrier

面向特定操作系统的应用 面向 WinCE 的 Embeded VC 面向 Symbian 的 C/C++ 集成开发环境 面向 Linux 的 GNU Tools (主要是 GCC/G++ )

操作系统开发 GCC/C++ (支持 uClinux, Linux, ECOS, uC/OS-II 等 )

其它 J2ME 等基于 JAVA 的编程

Page 188: ARM 指令集与编程

博创科技 嵌入互动

© 2005 博创科技

10.2 编程语言 汇编语言 C/C++语言

C 与汇编混合编程 Java语言

Page 189: ARM 指令集与编程

博创科技 嵌入互动

© 2005 博创科技

10.2.1 C 与汇编混合编程( 1 ) C/ASM 相互调用基于 ATPCS(ARM/Thumb Procdure Call Standard) ,也可简称 APCS C 中内嵌汇编

基于 ADS__asm{ 指令 [; /* 注释 */] ….. [ 指令 ]}

Page 190: ARM 指令集与编程

博创科技 嵌入互动

© 2005 博创科技

内嵌汇编的语法 操作数:作为操作数的寄存器和产量可以是 char\short\int 型的 C 表达式。 物理寄存器:不要使用复杂的 C 表达式;一般不要使用 R0~R3,R13

(SP),R14(LR) 不要使用寄存器代替变量

10.2.1 C 与汇编混合编程( 2 )

Page 191: ARM 指令集与编程

博创科技 嵌入互动

© 2005 博创科技

10.2.1 C 与汇编混合编程( 3 ) 交互规则:

寄存器规则: v1-v8 ( R4-R11 )用来保存局部变量 堆栈规则: FD 类型(满递减)堆栈 参数传递规则:如果参数个数小于等于 4 ,用 R0-R3 保存参数;参数个数多于 4 的情况下,剩余的参数传入堆栈 子程序结果返回规则:

结果为一个 32 位整数,通过 R0返回; 结果为一个 64 位整数,通过 R0、 R1返回; 对于位数更多的结果,通过内存传递。

Page 192: ARM 指令集与编程

博创科技 嵌入互动

© 2005 博创科技

Page 193: ARM 指令集与编程

博创科技 嵌入互动

© 2005 博创科技

参数个数多于 4 的情况下,剩余的参数传入堆栈

Page 194: ARM 指令集与编程

博创科技 嵌入互动

© 2005 博创科技

10.2.1 C 与汇编混合编程( 4 ) C调用汇编

C 代码…

extern void scopy(char *d, char *s);

Int main () {

Scopy ( dststr , srcstr )…

}

汇编代码AREA example, CODE, READONLY

EXPORT scopy

scopy

LDRB R2, [R0],#1

STRB R2, [R1], #1

CMP R2, R4

BNE scopy

MOV pc,lr

END

Page 195: ARM 指令集与编程

博创科技 嵌入互动

© 2005 博创科技

10.2.1 C 与汇编混合编程( 5 ) 汇编调用 C

汇编代码EXPORT callsum5

AREA example, CODE, READONLY

IMPORT sum5

callsum5

STMFD SP!,{LR} ;LR 入栈 ADD R1,R0,R0 ;R0=a,R1=b,R2=c

ADD R2,R1,R0

ADD R3,R1,R2

STR R3,[SP,#-4]! ;e in stack

ADD R3,R1,R1 ;R3=d

BL sum5 ;call R5, R0=result

ADD SP,SP,#4

LDMFD SP!,{PC}

END

C 代码Int sum5(int a, int b ,int c, int d, int e)

{

return (a+b+c+d+e);

}