ARM汇编语言

作者:郭孝星

微博:郭孝星的新浪微博

邮箱:[email protected]

博客:http://blog.csdn.net/allenwells

Github:https://github.com/AllenWells

一 寄存器

存储单元,32存储单元,4个字节的存储单元临时存放ALU运算结果的存储单元

Cortex-A R0到R15 为寄存器的编号

  • R0~R7 1组 8
  • R8~R12 2组 10
  • R13 7组 7
  • R14 7组 7
  • R15(PC) 1组
  • CPSR 1组
  • SPSR 6组

ARM一共有40寄存器,这些寄存器有8种工作模式和4种状态,如下所示:

4种状态

  • T=0;J = 1 处理器处于Jazelle状态
  • T = 0;J=0; 处理器处于 ARM 状态
  • T = 1;J=0 处理器处于 Thumb 状态
  • T = 1;J=1 处理器处于 ThumbEE 状态

8种模式

  • usr : 10000
  • fiq : 高优先级的中断 (10001)
  • irq : 低优先级的中断 (10010)
  • svc : 软中断和复位 (10011)
  • abort : 存和取 (10111)
  • undef : cpu不识别的指令 (11011)
  • system : (11111)
  • mon : 安全模式 (10110)

同名寄存器访问的问题

当前模式处在irq

mov r13,#0 (irq的r13 )

切换模式到fiq

mov r13,#1 (fiq的r13)

切换模式到undef

mov r13,#2 (undef的r13)

切换模式到abort

mov r13,#3 (abort的r13)

二 异常处理

4大步与3小步,由cpu内核自动完成,不需要用户写程序。

  1. pc -> lr_mode
  2. cpsr -> spsr_mode
  3. cpsr <-
    1. T=0,J =0
    2. I,F 禁止
    3. cpsr[4:0] = mode
  4. pc = 异常向量

举例1

当前系统发生了irq中断10

  1. pc ->lr_irq
  2. cpsr-> spsr_irq
  3. cpsr <-
    1. T=0,J=0;
    2. I,F 禁止
    3. cpsr[4:0] = 10010(irq)
  4. pc = 0x18

举例2

发生了一个软件中断

  1. pc -> lr_svc
  2. cpsr -> spsr_svc
  3. cpsr <-
    1. T=0,J=0;
    2. I,F 禁止
    3. cpsr[4:0] = 10011(svc)
  4. pc = 0x08

异常返回

movs pc,lr

s: spsr-> cpsr

三 协处理器

每一个协处理器里面有16个寄存器C0 ~ C15 mcr p15,0,r0,c1,c0,0

  • 4、ARM的后缀名:
  • T : 支持THUMB指令
  • D : 支持debug模式 ,支持片上调试
  • M : 64位的长乘法指令
  • I : 嵌入式ICE电路,用来获取cpu运算的状态
  • S : TDMI的缩写
  • E : 支持DSP指令 
  • J : 支持java字节码硬件加速的功能
  • F : 浮点运算

四 流水线

4.1 三级流水线

第一周期

pc = 0x8000
pc与fetch之间的关系  Fetch = *pc
F : mov
D : x
E : x

第二周期

pc = 0x8004
F : add
D : mov
E : x

第三周期

pc = 0x8008
F : sub      0x8008
D : add
E : mov      0x8000

第四周期

pc = 0x800c
F : and      0x800c
D : sub
E : add      0x8004

4.2 分支流水线举例

第一周期

pc = 0x8008
F : orr
D : sub
E : bl 0x8fec

第二周期

L相当于E单元的子单元
E :L pc -> lr = 0x8008
    pc = 0x8fec
F : and
D : x

第三周期

E : lr -4 -> lr = 0x8004
pc = 0x8ff0

F : orr
D : and

第四周期

pc = 0x8ff4
F : eor
D : orr
E : and

返回指令:

mov pc,lr (lr = 0x8004)

4.3 中断流水线

第一个周期(发生一个IRQ中断)

pc = 0x8008   -> 不变
F : mov       -> 不变
D : sub       -> 改变 DI(中断译码指令)
E : add       -> 不变

第二周期

pc = 0x800c
F : x
D : mov
E : EI(中断指令)

第三周期

E : L (异常处理)
    pc -> lr_irq = 0x800c
    pc = 异常向量(0x18)
    cpsr -> spsr_irq
    cpsr <- TJ I F [4:0] = 10010
F : B 0xaf00
D : x

第四周期

E : A(lr -4 -> lr_irq = 0x8008) 
pc = 0x1c
F : x
D : b 0xaf00

第五周期

pc = 0x20
F : x
D : x
E : b 0xaf00

第六周期

pc = 0xaf00
F :stmfd
D : x
E : x

第七周期

pc = 0xaf04
F : mov
D : stmfd
E : x

第八周期

pc = 0xaf08
F: ldr
D : mov
E : stmfd

stmfd是中断处理函数的第一条指令

中断返回: subs pc,lr,#4 (lr = 0x8008)

4.4 LDR流水线

M和W 是属于E单元的子单元,在M和W过程会占用E单元,占用E单元流水线阻隔

LDR互锁发生的条件

ldr指令中当前指令目的寄存器和下一条指令的源寄存器重名时会发生ldr互锁

LDM互锁:

LDMIA   R13!, {R0-R3}

这条指令执行需要连续计算4次地址,所以需要占用E单元,占用4个周期

五 ARM汇编和C进行传参的标准

ATPCS:函数参数要求:

int func (int a,int b,int c ,int d ,int e)
  • 第一个参数传给: R0
  • 第二个参数传给: R1
  • 第三个参数传给: R2
  • 第四个参数传给: R3
  • 第五个参数传给: 堆栈传递

参数的返回:

  • 32位的返回值: R0
  • 64位的返回值: 低32位R0 ,高32位R1

六 立即数的产生规则

一个字节的数,循环右移(ROR)0到30之间的偶数位得来的一个数就是立即数

判断规则:

0x1234,0x138,0x345,0xffffffff,0xf00012,0x12345678,0xf000000f,0x12,0x8
  x     y       x    x             x      x         y         y     y
  1. 展开成二进制
  2. 从左端第一个非0数的左端偶数位开始断开 ,再从右端第一个非0数的左端偶数位断开

    (保证断开的左端都为0 ,断开的右端都为0)

  3. 数断开之间的位数<= 8是立即数, > 8不是立即数

如下所示:

0x123
00 |01 0010 0011 |
0x348
00 | 11 0100 10 | 00

00 | 11 0100 0101 |

版权声明:当我们认真的去做一件事的时候,就能发现其中的无穷乐趣,丰富多彩的技术宛如路上的风景,边走边欣赏。

时间: 2024-08-04 12:32:07

ARM汇编语言的相关文章

ARM汇编语言实现while循环

.section .data .output: .ascii "%d\n\000" .section .text .global main main: mov ip, sp stmfd sp!, {fp,ip,lr,pc} sub fp, ip, #4 sub sp, sp, #80 @memory and register mov r3, # 1 mov r0,r3 loop: cmp r0,# 15 bge stop mov r1,# 1 add r2, r0, r1 mov r0

ARM 汇编语言源代码行的语法规则

ARM 汇编语言源代码行的语法规则 3.1 Syntax of source lines in assembly language 汇编器首先解析汇编语言源代码,然后把源代码汇编成目标文件.汇编语言源代码的每一行都要符合如下所示的语法格式:      {symbol} {instruction|directive|pseudo-instruction} {;comment} 语法格式中的以大括号分割的三个部分都是可选的. symbol通常表示一个标号.在指令和伪指令中,symbol总是一个标号.

[基于Android的ARM汇编语言系列]之一:ARM汇编语言开篇

作者:郭嘉 邮箱:[email protected] 博客:http://blog.csdn.net/allenwells github:https://github.com/AllenWell 这是[基于Android的ARM汇编语言系列]博文的开篇文章,这里会先介绍一下ARM处理器的大致分类和作用. 一 ARM处理器与ARM指令集 整个ARM处理器被分为三个部分: Classic Embedded Application Classic被称为经典系列. ARM1~ARM11一直都以数字来命名

[基于Android的ARM汇编语言系列]之二:原生程序的生成过程

作者:郭嘉 邮箱:[email protected] 博客:http://blog.csdn.net/allenwells github:https://github.com/AllenWell 所谓的原生程序指的是用C/C++编写的程序,下面来详细演示一下原生程序是怎么一步步生成汇编代码的. 这里编译的是一个简单的hello.c程序,如下所示: #include <stdio.h> int main(int argc, char* argv[]){ printf("Hello AR

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( Thumb)汇编语言程序中,以程序段为单位组织代码. 段是相对独立的指令或数据序列,具有特定的名称.段可以分为代码段和数据段,代码段的内

[基于Android的ARM汇编语言系列]之三:ARM汇编语言程序结构

作者:郭嘉 邮箱:[email protected] 博客:http://blog.csdn.net/allenwells github:https://github.com/AllenWell Android平台的ARM汇编是GNU ARM汇编格式,使用的汇编器是GAS(GNU Assembler),GAS有自己的一套语法结构.详细的内容可以查阅GAS语法结构官方手册. 我们先来看一个完整的ARM汇编程序: C代码: #include <stdio.h> int main(int argc,

[基于Android的ARM汇编语言系列]之四:ARM处理器的寻址方式

作者:郭嘉 邮箱:[email protected] 博客:http://blog.csdn.net/allenwells github:https://github.com/AllenWell 处理器的寻址方式是通过指令给出的地址码字段来寻找真实操作数地址的方式,ARM处理器支持9中寻址方式. 一 立即寻址 立即寻址指令后面的地址码部分为立即数(常量或常数),立即寻址多用于给寄存器赋值. 举例 MOV RO, #1234 指令执行后,R0=1234. 二 寄存器寻址 寄存器寻址中,操作数在寄存

[基于Android的ARM汇编语言系列]之五:ARM指令集与Thumb指令集

作者:郭嘉 邮箱:[email protected] 博客:http://blog.csdn.net/allenwells github:https://github.com/AllenWell 写在前面:本篇文章旨在大致介绍下ARM指令集的相关内容,这里也同时提供一个有详细解释和用例的待书签的PDF版本,方便大家查阅. ARM指令集详解 指令集是处理器的核心,ARM指令的基本格式如下所示: opcode {cond}{S}{.W\.N}Rd, Rn{.operand2} S:指定是否影响CPS

[基于Android的ARM汇编语言系列]之六:NEON指令集与VFP指令集

作者:郭嘉 邮箱:[email protected] 博客:http://blog.csdn.net/allenwells github:https://github.com/AllenWell NEON指令集与VFP指令集是ARM指令集的扩展,多用于多媒体编程和浮点运算. 一 Android平台使用NEON指令集与VFP指令集 Android NDK从r3版本开始也添加了对NEON指令集与VFP指令集的支持.使用方法如下所示: 1 运行时检测处理器是否支持NEON指令集与VFP指令集 Andr