• Home
  • About
    • tearorca photo

      tearorca

      Wishful thinking have to be willing to bet on clothing!

    • Learn More
    • Google+
    • Github
  • Posts
    • All Posts
    • All Tags
  • Projects

ARM汇编基础

17 Aug 2019

Reading time ~1 minute

  • ARM汇编基础
    • 工作模式
    • 寄存器
      • 不分组寄存器(R0—R7)
      • 分组寄存器(R8—R14)
      • PC指针(R15)
      • CPSR
      • SPSR
    • 指令介绍
      • .word
      • .macro
      • .global
      • .type
      • @
      • .align
      • .long
      • add
      • adr/adrl
      • b/bl
      • equ
      • ldr
      • ldm/ stm
      • mov
      • msr/mrs
      • mcr/mrc
      • str
      • sub
    • 参考链接

ARM汇编基础

工作模式

Arm处理器有七种工作模式,为的是形成不同的使用级别,以防造成对系统的破坏。不同模式可以访问的寄存器不同,可以运行的指令不同。

(1)usr(10000):普通应用程序运行的模式(应用程序)

(2)FIQ(10001):快速中断模式,以处理快速情况,高速数据传输

(3)IRQ(10010):外部中断模式,普通中断处理

(4)svc(10011):保护模式(管理模式),操作系统使用的特权模式(内核)

(5)abt(10111):数据访问中止模式,用于虚拟存储和存储保护

(6)und(11011):未定义指令终止模式,用于支持通过软件仿真硬件的协处理器

(7)sys(11111):系统模式,用于运行特权级的操作系统任务(armv4以上版本才具有)

注意:usr是普通模式,其他六种是特权模式,而除了usr和sys模式以外的五种模式是异常模式

寄存器

Arm处理器总共有37个寄存器其可以分为以下两类。

1、通用寄存器(31个)

不分组寄存器(R0—R7)

分组寄存器(R8—R14)

PC指针(R15)

2、状态寄存器(6个)

CPSR(1个)

SPSR(5个)

不分组寄存器(R0—R7)

在所有的运行模式下都使用同一个物理寄存器,它们未被系统用作特殊的用途。

分组寄存器(R8—R14)

对于R8~R12,当使用FIQ(快速中断模式)时访问寄存器R8_fiq~R12_fiq,当使用除FIQ模式以外的其他模式时,访问寄存器R8~R12

R13在ARM指令中常用作堆栈指针SP

R14称为子程序链接寄存器LR(Link Register),有两个特殊功能,一种是每一种模式下都可以用于保存函数的返回地址,另外就是异常处理后的返回地址,如中断。

PC指针(R15)

R15用作程序计数器(PC)对应一个物理寄存器,由于ARM体系结构采用了多级流水线技术,对于ARM指令集而言,PC总是指向当前指令的下两条指令的地址,即PC的值为当前指令的地址值加8个字节程序状态寄存器。

CPSR

程序状态寄存器,被用于标识各种状态。

N: 当两个表示的有符号整数运算时,1表示运算结果为负数,0表示结果为正或零。

Z:1表示运算的结果为零,0表示运算的结果不为零。对于CMP指令,1表示进行比较的两个数大小相等。

C:下面分四种情况讨论C的设置方法:

加法运算(包括比较指令CMN):当运算产生了进位时(无符号数溢出),C=1,否则C=0。

减法运算(包括比较指令CMP):当运算时产生了借位(无符号数溢出),C=0,否则C=1。

对于包含移位操作的非加/减运算指令,C为移出值的最后一位。

对于其他的非加/减运算指令,C的值通常不改变。

V:下面分两种情况讨论V的设置方法

对于加/减法运算指令,当操作数和运算结果为二进制的补码表示的带符号数时,V=1表示符号位溢出。

对于其他的非加/减运算指令,C的值通常不改变。

I:1 表示禁止外部(硬件)中断(IRQ)

F:1 表示禁止快速中断(FIQ)

T:1表示为thumb状态0为arm状态

M[4:0]:用来设置处理器的工作模式

SPSR

SPSR除usr、sys外,对应用于异常保护的CPSR的备份,异常时,保存CPSR值,异常退出时,将该值恢复到CPSR,以保证程序的正常运行,每一中异常运行模式(除usr和sys)有各自的物理寄存器。

指令介绍

.word

.word expression就是在当前位置放一个word型的值,这个值就是expression

_rWTCON:

.word 0x15300000

//就是在当前地址,即_rWTCON处放一个值0x15300000

.macro

宏名称 .MACRO [形式参数]

	........

	宏定义语句

	........

.ENDM

.global

告诉编译器后续跟的是一个全局可见的名字[可能是变量,也可以是函数名]

.type

.type:用来指定一个符号的类型是函数类型或者是对象类型, 对象类型一般是数据

@

GNU 汇编的规范,注释。

.align

.align的作用在于对指令或者数据的存放地址进行对齐,有些CPU架构要求固定的指令长度并且存放地址相对于2的幂指数圆整,否则程序无法正常运行,比如ARM。

.long

.long:定义4字节数据。

add

add r1,r2,#1 //表示r1=r2+1, 即寄存器r1的值等于寄存器r2的值加上1

adr/adrl

adr伪指令将基于PC相对偏移的地址值或基于寄存器相对偏移的地址值读取到寄存器中。adrl伪指令比adr伪指令可以读取更大范围的地址

格式:

ADR伪指令格式 :ADR{cond} register, expr

ADRL伪指令格式:ADRL{cond} register, expr

b/bl

相对跳转指令。两条指令不同之处在于bl指令除了跳转之外,还将返回地址(bl的下一条指定的地址)保存在lr寄存器中。类似于call。

equ

equ是类似于宏的作用,相当于#define。

ldr

是一个伪指令,从内存中读取数据到寄存器。

ldr r1,=4096 //r1 = 4096

ldr r1,[r2,#4] //将地址为r2+4的内存单元数据读取到r1中去

ldr r1,[r2] //将地址为r2的内存单元位数据读取到r1中去

ldr r1,[r2],#4 //将地址为r2的内存单元的数据读取到r1中,然后r2=r2+4

ldm/ stm

批量访问内存,内存中批量读取数据到寄存器。主要用于现场保护,数据复制,参数传送

mov

把一个寄存器的值赋给另一个寄存器,或者把一个常数赋值给寄存器。

mov r1,r2 //r1 = r2

mov r1,#4096 //r1 = 4096

msr/mrs

程序状态寄存器访问指令。ARM处理器中有一个程序状态寄存器(cpsr),他用来控制处理器的工作模式,设置中断的总开关。

msr cpsr,r0 //复制r0到cpsr中

mrs r0,cpsr //复制cpsr到r0中

mcr/mrc

MCR指令将ARM处理器的寄存器中的数据传送到协处理器的寄存器中。如果协处理器不能成功地执行该操作,将产生未定义的指令异常中断。

MRC指令将协处理器的寄存器中数值传送到ARM处理器的寄存器中。如果协处理器不能成功地执行该操作,将产生未定义的指令异常中断。

str

是一条伪指令,把寄存器的值存储到内存中。

str r1,[r2,#4] //将r1的数据保存到地址为r2+4的内存单元中

str r1,[r2] //将r1的数据保存到地址为r2的内存单元中

str r1,[r2],#4 //将r1的数据保存到地址为r2的内存单元中,然后r2=r2+4

sub

sub r1,r2,#1 //表示r1=r2-1

参考链接

https://blog.csdn.net/daiyibo123/article/details/50240433

https://blog.csdn.net/u013216061/article/details/78139123

https://www.cnblogs.com/wrjvszq/p/4199682.html

https://blog.csdn.net/richard1230/article/details/79812966#ldmstm%E6%8C%87%E4%BB%A4



Share Tweet +1