blog:asm:arm_instruction_1

ARM指令与汇编

寻址方式与指令格式

根据指令中地址码字段来寻址操作数地址的方式。

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

MOV R1, R2        ; R2 -> R1
SUB R0, R1, R2    ; R1 - R2 -> R0

指令中操作码字段后面的地址码部分就是操作数本身, 数据就包含在指令中。取出指令也就取出了可以立即使用的操作数

SUBS R0, R0, #1     ; R0 - 1 -> R0
MOV  R0, #0xff00    ; 0xff00 -> R0

ARM指令集特有的寻址方式, 第2个操作数与第1个操作数结合前先进行移位操作

MOV  R0, R2, LSL #3      ; R2的值左移3位,结果放入R0中
ANDS R1, R1, R2, LSL R3  ; R2左移R3位,然后与R1相与,结果存入R1中

可使用的移位操作如下:

*LSL*: 逻辑左移(Logical Shift Left) 低位补0*LSR*: 逻辑右移(Logical Shift Right) 高位补0*ASR*: 算术右移(Arithmetical Shift Right) 移位过程中保持符号位不变,即如果源操作数为正数,则高位补0, 如果源操作数为负数,则高位补1*ROR*: 循环右移(Rotate Right) 字的低端移出的位填入高端空出的位。*RRX*: 带扩展的循环右移(Rotate Right eXtended by 1 place) 操作数右移移位,高端空出的位用原C标志填充。

指令中地址码给出的是寄存器编号,操作数保存在寄存器指定地址的存储单元中,即寄存器存放的是操作数的地址

LDR R1, [R2]        ; R2中为操作数的地址,取出地址中的数据保存在R1中

将寄存器中的内容与给定的偏移量相加,得到操作数的有效地址。 基址寻址用于访问基址附近的存储单元,一般用于查表,数组操作…

LDR R2, [R3, #0x0f]     ; 将R3中的数值作为基址加上0xf作为操作数的地址,取出地址的数据保存在R2中。
STR R1, [R0, #-2]       ; 将R0中的数值作为基址减2作为操作数的地址,把R1中的内容保存在此地址中。

一次可以传送多个寄存器的值,允许一条指令传送16个寄存器的任何子集

LDMIA R1!, {R2-R7, R12}     ; R1指向地址中的数据读出到R2到R7和R12中, R1自动加1
STMIA R0!, {R3-R6, R10}     ; 将R3-R6和R10中的数据保存在R0指定的地址中,R0自动加1

寄存器子集的顺序由小到大排列,连续的寄存器可用“-“连接,否则用”,”分开书写

I: 地址增加D: 地址减小A: 数据读取后,地址加减B: 数据读取前, 地址加减

堆栈是按特定顺序进行存取的存储区,操作顺序为“先进后出” 或 “后进先出” 堆栈寻址使用一个专门的寄存器(堆栈指针sp)指向一块存储区域,指针指向的存储单元就是堆栈的栈顶。

生长方向 递增堆栈: 向高地址方向生长 Ascend 递减堆栈: 向低地址方向生长 Descend

根据堆栈指针指向的位置又可以分为满堆栈和空堆栈 满堆栈: 堆栈指针指向最后压入堆栈的有效数据项 Full 空堆栈: 堆栈指针指向下一个要压入的空位置 Empty

根据生长方向和堆栈指针位置可以组合出来4种类型的堆栈

满递增: 堆栈通过增大存储器的地址向上增长,堆栈指针指向含有有效数据项的最高地址。指令如 LDMFA STMFA等 空递增: 堆栈通过增大存储器的地址向上增长,堆栈指针指向堆栈上的第一个空位置。指令如 LDMEA STMEA等 满递减: 堆栈通过减小存储器的地址向下增长,堆栈指针指向含有有效数据项的最低地址。指令如 LDMFD STMFD等 空递减: 堆栈通过减小存储器的地址向下增长,堆栈指针指向堆栈的下一个空地址。指令如 LDMED STMED等

举例:

STMFD SP!, {R1-R7, LR}          ; 将R1-R7, LR入栈, 满递减堆栈
LDMFD SP!, {R1-R7, LR}          ; 数据出栈,存放如R1-R7, LR , 满递减堆栈

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

例:

BL   ROUTE1     ; 跳转到ROUTE1子程序
BEQ  LOOP       ; 条件跳转到LOOP标号
User User mode, 程序通常运行在这种模式下FIQ (entered when a high priority (fast) interrupt raised)IRQ (entered when a low priority (normal) interrupt raised)Supervisor (entered on reset and when a Software Interrupt instruction is executed)Abort (used to handle memory access violations)Undef (used to handle undefined instructions)System (特权工作模式,和User Mode使用同一套寄存器)

![ARM Register Organisation][ARM Register]

ARM总共有37个寄存器,每个寄存器都是32bit

1个用于PC(程序计数器) 1个用于当前的程序状态寄存器CPSR 5个用于保存程序状态寄存器SPSR 30个通用寄存器

这些寄存器根据工作模式分为7组

R13 用于堆栈指针SP R14 用于连接寄存器LR R15 用于程序计数器

![ARM CPSR Register][ARM CPSR]

条件码标志 copies of the ALU status flags

N = Negative result from ALU flagZ = Zero result from ALU flagC = ALU operation Carried out (进位)V = ALU operation oVerflowed (溢出)

Interrupt Disable bits Bit[7:6]

I = 1, disable the IRQF = 1, disable the FIQ

ARM/Thumb Mode Bit[5]

T = 0, ARM stateT = 1, Thumb state

Working mode Bit[4:0]

当处理器在ARM模式下执行时: 所有指令长度为32bit 所有指令必须以字对齐,所以PC指针的bit[1:0]应该等于0

当跳转指令执行时,R14用于保存根据PC计算得到的返回地址

异常向量表

![ARM exception vector table][ARM Exception Vector Table]

异常处理流程 异常产生时:

. 拷贝CPSR to SPSR_<mode>
. 设置相应的CPSR状态位
. 将返回地址存储在LR_<Mode>
. 将PC设置为对应的向量地址

从异常返回:

. 将SPSR_<mode>恢复到CPSR
. 将LR_<mode>恢复到PC

基本格式

<opcode> {<cond>} {S} <Rd>,<Rn> {,<operand2>}

<>内的项是必须的, {}内的项是可选的
opcode 指令助记符, 如 LDR, STR等cond 执行条件,如EQ,NE等,如果没有指定cond,则默认为AL(无条件执行)S 是否影响CPSR的条件码标志Rd 目的寄存器Rn 第一个操作数的寄存器operand2 第二个操作数

`立即数#immed_8r`

立即数,该常数必须对应8位位图,即该常数由一个8位的常数循环移位偶数位得到

合法常量: 0x3FC, 0, 0xF0000000, 200,
非法常量: 0x1FE, 511, 0xFFFF, 0x1010, 0xF0000010

例: MOV R1, #1

寄存器方式 Rm

操作数为寄存器的值 例如:

SUB R1, R1, R2 ; R1 - R2 → R1 MOV PC, R1 ; PC = R1

寄存器移位方式 Rm, shift

将寄存器移位后的结果作为操作数,但寄存器Rm的值保持不变

ADD R1, R1, LSL #3 ; R1 = R1 * 9 SUB R1, R1, R2, LSR #2 ; R1 = R1 - R2 / 4

![ARM condition code][ARM Condition Code]

对于thum指令集,只有B指令具有条件执行能力

the Harvard architectrue

哈弗结构是一种将指令和数据分开存储的计算机结构。Harvard architecture这一术语来源于Harvard Mark I型继电器式计算机。 Hardvard Mark I是IBM的自动顺序控制计算机ASCC(Automatic Sequence Controlled Calculator), 被哈佛大学的研究人员称为Mark I(马克一号) Mark I 将指令存储在纸带上,数据存储在机电计数器上,处理器首先到指令存储器中读取指令内容,解码后得到数据地址,再到相应的数据存储器中读取数据。 程序指令和数据分开存储。数据和指令的存取可以分开进行,可以是指令和数据的有不同的宽度。

使用哈佛结构的处理器和微控制器有很多,例如Atmel的AVR系列,ARM公司的ARM9, ARM10, ARM11… …

![the Hardvard architecture, from wikipedia][Harvard Architecture]


the von Neumann architecture

![the von Neumann architectrue, from wikipedia][Von Neumann Architecture]

冯诺依曼体系结构描述了一种电子数字计算机,由以下几部分组成: 1. Processing unit: ALU(arithmetic logic unit, processor registers) 2. Control unit: instruction register and Program Counter 3. a memory to store both data and instructions 4. input and output machanisms

典型情况下完成一个指令需要3个步骤: 取指,译码,执行。 由于取指令和存取数据都需要从同一个存储空间存取,并使用同一总线传输。他们不能重叠执行,只能顺序执行。

  • blog/asm/arm_instruction_1.txt
  • 最后更改: 2025/02/02 23:10
  • 127.0.0.1