ARM汇编编程基础之一 —— 寄存器
ARM的汇编编程,本质上就是针对CPU寄存器的编程,所以我们首先要弄清楚ARM有哪些寄存器?这些寄存器都是如何使用的?
ARM寄存器分为2类,普通寄存器和状态寄存器
寄存器类别 |
寄存器在汇编中的名称 |
各模式下实际访问的寄存器 |
||||||
用户 |
系统 |
管理 |
中止 |
未定义 |
中断 |
快中断 |
||
通用寄存器和程序计数器 |
R0(a1) |
R0 |
||||||
R1(a2) |
R1 |
|||||||
R2(a3) |
R2 |
|||||||
R3(a4) |
R3 |
|||||||
R4(v1) |
R4 |
|||||||
R5(v2) |
R5 |
|||||||
R6(v3) |
R6 |
|||||||
R7(v4) |
R7 |
|||||||
R8(v5) |
R8 |
R8_fiq |
||||||
R9(SB,v6) |
R9 |
R9_fiq |
||||||
R10(SL,v7) |
R10 |
R10_fiq |
||||||
R11(FP,v8) |
R11 |
R11_fiq |
||||||
R12(IP) |
R12 |
R12_fiq |
||||||
R13(SP) |
R13 |
R13_svc |
R13_abt |
R13_und |
R13_irq |
R13_fiq |
||
R14(LR) |
R14 |
R14_svc |
R14_abt |
R14_und |
R14_irq |
R14_fiq |
||
R15(PC) |
R15 |
|||||||
状态寄存器 |
CPSR |
CPSR |
||||||
SPSR |
无 |
SPSR_abt |
SPSR_abt |
SPSR_und |
SPSR_irq |
SPSR_fiq |
请看上表的第2列,普通寄存器总共16个,分别为R0-R15;状态寄存器共2个,分别为CPSR和SPSR
普通寄存器中特别要提出来的是R13、R14、R15。
R15别名PC(program counter),中文称为程序计数器,它的值是当前正在执行的指令在内存中的位置(不考虑流水线的影响,参见流水线对PC值的影响一文),而当指令执行结束后,CPU硬件会自动将PC的值加上一个单位,从而使得PC的值为下一条即将执行的指令在内存中的位置,这样CPU硬件就可以根据PC的值自动完成取指的操作。正是由于有PC的存在,以及CPU硬件会自动增加PC的值,并根据PC的值完成取指操作,才使得CPU一旦上电就永不停歇地运转,由此可见PC寄存器对于计算机的重要性。对于我们进行汇编程序编写而言,PC寄存器亦是十分重要,因为当程序员通过汇编指令完成了对PC寄存器的赋值操作的时候,其实就是完成了一次无条件跳转,这一点非常重要,请务必要牢记。
R14别名LR(linked register),中文称为链接寄存器,它与子程序调用密切相关,用于存放子程序的返回地址,它是ARM程序实现子程序调用的关键所在。下面我们用C语言中对子程序调用的实现细节来说明LR是如何被使用的。
1 int main(void)
2 {
3 int k, i = 1, j = 2;
4 addsub(i, j);
5 k = 3;
6 }
7 int addsub(int a, int b)
8 {
9 int c;
10 c = a + b;
11 return c;
12 }
对于上面的程序,编译器会将第4行编译为指令:BL addsub,将第11行编译为指令:MOV pc, lr。(关于BL和MOV指令详见“基本寻址模式与基本指令”)
在这里,关键指令BL addsub会完成2件事情:1、将子程序的返回地址(也就是第5行代码在内存中的位置)保存到寄存器LR中;2、跳转到子程序addsub的第1条指令处。这样就完成了子程序的调用。而指令MOV pc, lr则将保存在lr中的返回地址赋给pc,这样就完成了从子程序的返回。由此可见,lr是用于存放子程序的返回地址的。
另外一个要引起注意的问题是,如果子程序又调用了孙子程序,那么根据前面的分析,在调用孙子程序时,lr寄存器中的值将从子程序的返回地址变为孙子程序的返回地址,这将导致从孙子程序返回子程序没有问题,但从子程序返回父程序则会出错。那么这个问题如何解决呢?其实,如果我们编写的是C程序,那么我们一点也不用担心,因为编译器会为我们考虑一切,针对这个问题,编译器会在孙子程序的入口处增加入栈操作将lr的值入栈,然后在孙子程序的返回处增加出栈操作,将lr的值恢复,从而解决这个难题。不过我们一定要保持头脑的清醒,因为你要知道,我们现在是在编写汇编子程序,此时编译器已经不能在这方面给我们提供保障,所以当你在编写汇编子程序的时候,发现该子程序还要再调用孙子程序,那么请你务必记住,一定要在子程序的入口处保存lr寄存器的值。
好了,现在轮到寄存器R13了,R13又名SP(stack pointer),中文名称栈指针寄存器。顾名思义,它是用于存放堆栈的栈顶地址的。也就是说,每次当我们进行出栈和入栈的时候,都将根据该寄存器的值来决定访问内存的位置(即:出入栈的内存位置),同时在出栈和入栈操作完成后,SP寄存器的值也应该相应增加或减少。这里要特别说明的是,其实在32位的ARM指令集中没有专门的入栈指令和出栈指令,所以并不是一定要用SP来作为栈指针寄存器,除了PC外,任何普通寄存器均可作为栈指针寄存器,只不过,约定俗成都使用SP罢了。我们将在“其它寻址模式与其它指令”一文中见到ARM中使用SP作为栈指针寄存器的出入栈指令。
寄存器R0-R12是普通的数据寄存器,可用于任何地方。在不涉及ATPCS规则(在“ATPCS与混合编程”一文中详细介绍)的情况下,他们并没有什么特别的用法。
状态寄存器CPSR(current program status register),中文名称:当前程序状态寄存器,顾名思义它是用于保存程序的当前状态的。那么,程序的哪些状态是需要保存的呢?
上图是CPSR寄存器的内容,主要由以下部分组成:
1、条件代码标志位。它们是ARM指令条件执行的依据。
N:运算结果的最高位反映在该标志位。对于有符号二进制补码,结果为负数时N=1,结果为正数或零时N=0;
Z:指令结果为0时Z=1(通常表示比较结果“相等”),否则Z=0;
C:当进行加法运算(包括CMN指令),并且最高位产生进位时C=1,否则C=0。当进行减法运算(包括CMP 指令),并且最高位产生借位时C=0,否则C=1。对于结合移位操作的非加法/减法指令,C为从最高位最后移出的值,其它指令C通常不变
V:当进行加法/减法运算,并且发生有符号溢出时V=1,否则V=0,其它指令V通常不变
2、控制位。它们将控制CPU是否响应中断。
I:中断禁止位,当I位置位时,IRQ中断被禁止
F:快中断禁止位,当F位置位时,FIQ中断被禁止
T:反映了CPU当前的状态。当T位置位时,处理器正在Thumb状态下运行;当T位清零时,处理器正在ARM状态下运行
3、模式位
包括M4、M3、M2、M1和M0,这些位决定了处理器的模式(关于处理器模式详见“ARM处理器模式与异常初步”一文)。
总共有7种模式:用户、快中断、中断、管理、中止、未定义、系统,分别会用于不同的情况和异常。由此可见,不是所有模式位的组合都定义了有效的处理器模式,如果使用了错误的设置,将引起一个无法恢复的错误。
SPSR(saved program status register),中文名称:保存的程序状态寄存器
该寄存器的结构与CPSR完全一样,在异常发生时(关于异常,请参见“ARM处理器模式与异常初步”一文),由硬件自动将异常发生前的CPSR的值存放到SPSR中,以便将来在异常处理结束后,程序能恢复原来CPSR的值。
ARM汇编编程基础之一 —— 寄存器的更多相关文章
- 《深入浅出嵌入式底层软件开发》—1. ARM汇编编程基础
1.1 ARM CPU寄存器 ARM的汇编编程,本质上就是针对CPU寄存器的编程,所以要搞清楚ARM有哪些寄存器:ARM寄存器分为两类:普通寄存器和状态寄存器:普通寄存器一共有16个,分别为R0——R ...
- 3.1 ARM汇编编程概述
1. 汇编编程 为什么要学习汇编 1). Bootloader初始化 2). Linux kernel 3). 高效 2. ARM汇编分类 1. ARM标准汇编:ARM公司得汇编器适合在Windows ...
- ARM汇编编程概述
1.为什么需要学些汇编指令 2.ARM汇编指令分类 3.汇编程序框架 4.编程准备 +++++++++++++++++++++++++++++++++++ 1.为什么需要学些汇编指令 bootload ...
- [国嵌笔记][024][ARM汇编编程概述]
汇编程序用途 1.在bootloader与内核初始化时,还没有建立C语言运行环境,需要用到汇编程序 2.在对访问效率要求很高的情况下,需要用到汇编程序 ARM汇编分类 1.ARM标准汇编:适合于Win ...
- ARM的编程模式及寄存器
根据朱老师的课程及下面博客整理 http://blog.chinaunix.net/uid-20443992-id-5700979.html ARM 采用的是32位架构 ARM 约定: Byte : ...
- ARM 汇编访问 CPSR / SPSR 寄存器 【 msr ,mrs 】
状态寄存器访问过程:读 - 改 - 写 读 CPSR / SPSR 指令[ mrs ] 格式:<opcode><cond> Rn, cpsr/spsr 写 CPSR / ...
- ARM汇编
ARM汇编 ISA ISA即指指令集架构(Instruction Set Architecture)是与程序设计有关的计算机架构的一部分,包括本地数据类型.指令.寄存器.地址模式.内存架构.中断和意外 ...
- iOS 逆向之ARM汇编
最近对iOS逆向工程很感兴趣. 目前iOS逆向的书籍有: <Hacking and Securing IOS Applications>, <iOS Hacker's Handboo ...
- GNU ARM 汇编基础
ARM GNU汇编基础 0 前言 全文补充提醒: 笔者在阅读ARM官方文档及查阅实际的u-boot源码中的汇编代码后,发现了一些不同于ARM官方文档中的汇编语法,查阅相关资料后,才发现主要由于汇编器的 ...
随机推荐
- 基于canvas将图片转化成字符画
字符画大家一定非常熟悉了,那么如何把一张现有的图片转成字符画呢?HTML5让这个可能变成了现实,通过canvas,可以很轻松实现这个功能.其实原理很简单:扫描图片相应位置的像素点,再计算出其灰度值,根 ...
- linux - JDK 环境
JDK安装 vi /etc/profile # 添加环境变量 export JAVA_HOME=/usr/local/jdk1.8.2_45 export CLASSPATH=.:$JAVA_HOME ...
- Floyd判圈算法 UVA 11549 - Calculator Conundrum
题意:给定一个数k,每次计算k的平方,然后截取最高的n位,然后不断重复这两个步骤,问这样可以得到的最大的数是多少? Floyd判圈算法:这个算法用在循环问题中,例如这个题目中,在不断重复中,一定有一个 ...
- c++刷题(39/100)笔试题3
题目1: 现在你需要用一台奇怪的打字机书写一封书信.信的每行只能容纳宽度为100的字符,也就是说如果写下某个字符会导致行宽超过100,那么就要另起一行书写 信的内容由a-z的26个小写字母构成,而每个 ...
- git与代码托管工具
1.git初识 git是一个版本管理工具,用来管理项目的不同的版本,记录下不同的提交记录,git还可以构建不同的分支,用来给不同的人来推送使用. 推荐的git教程:https://www.cnblog ...
- linux动态追踪神器——Strace实例介绍【转】
Strace是Linux下一款通用的进程动态跟踪工具,用来追踪程序执行时的系统调用和所接收的信号.其应用方法如下图(部分). 首先,简单说说它的使用参数,Strace的参数包括输出参数.过滤参数.统计 ...
- linux服务器账号密码正确无法登录
登录服务器时,发现密码错误,输入后还是错误不能登录 最后发现登录日志中有pam_tally2(sshd:auth): user root (0) tally 53, deny 6 less /var/ ...
- jexus - 分析日志文件
1.统计IP访问次数 awk '{print $3}' default |sort -n|uniq -c|sort -rn|head
- vector的reserve和resize(转)
转自:http://www.cnblogs.com/qlee/archive/2011/05/16/2048026.html vector 的reserve增加了vector的capacity,但是它 ...
- java 多态缺陷
一,会覆盖私有方法 package object; class Derive extends Polymorphism{ public void f1() { System.out.println(& ...