嵌入式Linux ARM汇编(三)——ARM汇编指令

一、ARM汇编语言基本结构

AREA Init, CODE, READONLY

 ENTRY

 Start

  LDR R0, =0x3FF5000

  LDR R1, 0xFF

  STR R1, [R0]

  LDR R0, =0x3FF5008

  LDR R1, 0x01

  STR R1, [R0]

  ... ... ... ... ... ...

  END

二、ARM处理器寻址方式

    寻址方式是根据指令中给出的地址码字段来实现寻找真实操作数地址的方式。ARM处理器有九种寻址方式,寄存器寻址、立即数寻址、寄存器偏移寻址为数据处理指令操作数寻址方式,寄存器间接寻址、基址寻址、多寄存器寻址、堆栈寻址、相对寻址为存储器访问指令操作数寻址方式。

1、寄存器寻址

    操作数的值存在寄存器中,指令中的地址码字段指出的是寄存器编号,指令执行时直接取出寄存器值操作。例如:

MOV R0R1

SUB R0R1R2

2、立即寻址

    立即寻址指令中的操作码字段部分后面的地址码部分就是操作数本身,即数据包含在指令当中。例如:

MOV R0,#0xff

立即数要以“#”为前缀,十六进制以“0x”表示

3、寄存器偏移寻址

    寄存器偏移寻址是ARM指令集特有的寻址方式,当第2操作数是寄存器,在执行操作之前,可以做一次移位操作

MOV R0,R2,LSL #3

ANDS R1,R1,R2,LSL R3

4、寄存器间接寻址

        寄存器间接寻址指令中的地址码给出的是一个通用寄存器的编号,所需的操作数保存寄存器指定地址的存储单元中,即寄存器为操作数的地址指针

LDR   R1,[R2]          ;R2指向的单元中的数据保存再R1

SWP   R1R1,[R2]       ;将寄存器R1的值和R2指向的单元中进行内容交换

5、基址寻址

    基址寻址就是将基址寄存器的内容与指令中给出的偏移量进行相加,形成操作数的有效地址。基址寻址用于访问基址附近的存储单元,常用于查表、数组操作以及功能不见寄存器访问等

LDR   R2[R3,#0x0c]     ; 读取R3 0x0c地址指向的存储单元的内容,放入R2

STR   R1,[R0,#-4]!       ;先R0=R0-4,然后把R1的值寄存到R0所指向的单元中

LDR   R1,[R0,R3,LSL #1]  ;R0 R3*2地址上的单元的内容读出,并存入R1

6、多寄存器寻址

    多寄存器寻址即一次可传送几个寄存器的值,允许一条指令传送16个寄存器的任何子集或所有的存储器

LDMIA   R1!,{R2-R7,R12};将R1指向的单元中的数据读出到R2---R7R12中(R1自自动 )

STMIA   R0!{R2-R7R12};将R2---R7R12中的数据一次读入到R0指向的单元中(R0自动 )

7、堆栈寻址

        堆栈是一种按特定顺序进行存取的存储区,操作顺序分为先进后出后进先出,堆栈寻址是隐含的,它使用一个专门的寄存器(堆栈指针)指向的存储区域(堆栈),指针所指向的存储单元即是堆栈的栈顶。

STMFD    SP!,{R1-R7LR}    ;将R1---R7LR入栈。满递减堆栈

LDMFD    SP!,{R1-R7LR}  ;数据出栈,放入R1---R7LR寄存器,满递减堆栈

8、块拷贝寻址

        多寄存器传送指令用于将一块数据从存储器的某一位置拷贝到另一位置

STMIA R0!,{R1-R7} ;R1R7的数据保存到存储器中。
   ;存储指针在保存第一个值之后增加,
   ;增长方向为向上增长。
STMIB R0!,{R1-R7} ;R1R7的数据保存到存储器中。
   ;存储指针在保存第一个值之前增加,
   ;增长方向为向上增长。

9、相对寻址

        相对寻址是基址寻址的一种变通。由程序计数器PC提供基址地址,指令中的地址码字段为偏移量。两者相加后得到的地址即为操作数的有效地址。

三、指令格式

ARM指令的基本格式:

<opcode>[<con>][S] <Rd>, <Rn>{,operand2}

opcode:指令助记码,如:MOV

con:执行条件,如NE,EQ

S:是否影响CPSR寄存器的值,设置时影响CPSR

Rd:目标寄存器

Rn:第一个操作数的寄存器

operand2:第二个操作数

条件码表

wKioL1dRVCfixH0PAAGVNga3ke4554.png