跳至主要内容

32位ARM汇编语言(一)寄存器介绍

http://ift.tt/2EiY3sg


ARM 基本约定

  • Byte:8 bits
  • Halfword: 16bits
  • Word:32 bits

大部分的ARM core提供:
- ARM 指令集(32-bit)(中断处理,需要32位)
- Thumb指令集(16-bit)(最先推出的,每个指令16位)
- Thumb2 指令集(16&32bit)(ARMv7时退出,混合指令)
- ARM Thumb 互相可以转换

ARM处理器工作模式(7种)

  • 7种工作模式:
Mode 解释
User 非特权模式,大部分任务执行在这种模式
FIQ 当一个高优先级(fast)中断产生时将会进入这种模式(ARM的FIQ Signal被触发所产生的异常)
IRQ 当一个低优先级(normal)中断产生时将会进入这种模式(ARM的IRQ Signal被触发所产生的异常 )
Supervisor 当复位或软中断指令执行时将会进入这种模式
Abort 当存取异常时将会进入这种模式(也就是读取内存异常)
Undef 当执行未定义指令时进入这种模式
System 使用和User模式相同寄存器集的特权模式
  • 注意:

    1:除User(用户模式)是Normal(普通模式)外,其他6种都是Privilege(特权模式)
    2:Privilege中除Sys模式外,其余5种为异常模式
    3:各种模式的切换,可以是普通程序员通过代码主动切换(通过写cpsr寄存器);也可以是CPU在某些情况下自动切换
    4:各种模式下权限和可以访问的寄存器不同

ARM寄存器

ARM 寄存器一共有37个32位寄存器

其中,30个为”通用“寄存器,r1-r14

  • 未分组的寄存器:r1-r7,只有一个寄存器
  • 分组的寄存器:
    • r8-r14:有多个同名寄存器
    • r8-r12:两个
    • r13-r14:6个 r13(sp),R14(lr)
  • 一个固定的程序计数器:pc(又称r15),也就是x86 中的eip
  • 6个状态寄存器:cpsr ,spsr

但是这个37个寄存器是不同同时访问的,一种模式对应一套,规则如下图

Abort Mode

FIQ Mode

IRQ Mode

SVC Mode

Undef Mode

User Mode

  • 其中:sp(r13 )- 堆栈指针
  • lr(r14)- 连接寄存器,用于保存返回地址
  • cpsr - 当前程序的状态寄存器
    保存当前程序的种种状态
    包括:条件标志位,中断标志位,当前处理器模式等
    
    


    图片参考博客地址,但是不全,这个图比较老了,后期更新架构了添加了几个标志位

  • spcr -备份的程序状态寄存器

    cpsr寄存器的备份,当异常发生时,spsr用于保存cpsr的当前值,从异常退出时可由spcr来恢复cpsr,用于用户模式与系统模式不属于异常模式,所以没有spcr
    
    

例子:

(1)跳转到指定地址
mov pc,lr   //直接修改pc,完成跳转
bx lr       //跳转到lr保存的地址

(2)在函数入口保存寄存器信息

stmfd sp!,{r11,lr}    //保存大括号中的寄存器到栈中,从右往左

(3)使用ldm 指令修改pc,完成函数返回

stmfd sp!,{r11,lr}  //保存大括号中的寄存器到栈中,从右往左


小结

  • ARM共有37个寄存器,都是32位长度
  • 32个寄存器中30个为通用型,一个为固定pc,一共固定用于cpsr,5个固定用作5中异常模式下的spsr
  • cpsr中各个bit位表明了cpu的某些状态信息,这些信息是非常重要的
  • cpsr 中的I,F 为和开中断,关中断有关,cpsr中的mode位(bit4~bit0共5位)决定了CPU的工作模式, 在uboot代码中会使用汇编进行设置
  • pc(Program control register)为程序指针,PC指向哪里,CPU就会执行那条指令,整个cpu中就只有一个PC

The post 32位ARM汇编语言(一)寄存器介绍 appeared first on cole.

http://ift.tt/2DLuJty ArmAsm, ARM, asm January 29, 2018 at 07:44PM

评论

此博客中的热门博文

反Hook 之自己实现GetProcAddress和LoadLibraryA(c++ version)

http://ift.tt/2AocAD0 // 课上练习.cpp : 定义控制台应用程序的入口点。 // #include "stdafx.h" #include <windows.h> //要实现的功能: /* 自己实现GerProcAddress LoadLibraryA */ //思路: /* GerProcAddress和LoadLibraryA都是在Kernel32.dll中的 首要的任务就是找到Kernel32.dll,然后遍历IAT就能找到这两个函数 现在首要的难点就是如何找到kernel32.dll() 通过dll的加载顺序可以找到,而且虽然需要使用未文档化的API,但是好在windgb可以直接看,而且用到的也并不是很多 懒得去晚上搜了,直接自己实现一个得了,作为演示,能用就行(最好还是搜一个正规的结构体) */ /* 0: kd> dt _TEB /a nt!_TEB +0x000 NtTib : _NT_TIB +0x01c EnvironmentPointer : Ptr32 Void +0x020 ClientId : _CLIENT_ID +0x028 ActiveRpcHandle : Ptr32 Void +0x02c ThreadLocalStoragePointer : Ptr32 Void +0x030 ProcessEnvironmentBlock : Ptr32 _PEB //首先实现部分TEB结构体,因为只需要用的PEB的部分,所以实现到这就ok了 */ //构建 TEB typedef struct _TEB { //保证0x30是peb的结构体就ok了 struct _tem { DWORD a1; DWORD a2; DWORD a3; DWORD a4; DWORD a5; DWORD a6; DWORD a7; DWORD a8; DWORD a9; DWORD a10; ...

IDA动态调试ELF中遇到的问题(1)

https://ift.tt/2Gxnf2F 遇到 got SIGCHLD singal(child status has changed)...这种提示 singal fork了子进程 直接点yes,然后继续单步执行,出来提示 pass to application就行了 内存查看 用od习惯了之后,凡事都想右键看一下内存,但是IDA中好像没有那么如意, 目前只是在栈中右键发现有查看hex的选项 动态调试的时候的nop ida保存动态调试的时候修改的数据 方法一:在程序运行的时候保存 The post IDA动态调试ELF中遇到的问题(1) appeared first on cole . https://ift.tt/2q9Qf5g WHATEVER April 05, 2018 at 09:44AM

32位ARM汇编语言(四)数据处理指令

http://ift.tt/2Gwa4v5 基本指令介绍 数据传送指令 比较指令 cmp{条件}操作数1,操作数2 CMN{条件}操作数1,操作数2 TST{条件},操作数1,操作数2 TEQ{条件} 操作数1,操作数2 算数逻辑运算指令 ADD{条件}{S}目的寄存器,操作数1,操作数2 ADC{条件}{S}目的寄存器,操作数1,操作数2 RSB{条件}{S}目的寄存器,操作数1,操作数2 RSC{条件}{S}目的寄存器,操作数1,操作数2 AND{条件}{S}目的寄存器,操作数1,操作数2 EOR{条件}{S}目的寄存器,操作数1,操作数2 BIC{条件}{S}目的寄存器,操作数1,操作数2 基本指令介绍 数据传送指令 数据传送指令用于在寄存器和储存器中之间进行数据的双向传输 比如:MOV ,MVN 算数逻辑运算指令 完成常用的算术与逻辑运算,该类指令不但将运算结果保存在目的寄存器中,同时更新CPSR中相应条件表示位 比如:ADD,ADC,SUB,SBC,RSB,RSC,AND,ORR,EOR,BIC 比较指令 不保存运算结果,只更新CPSR中相应的条件标志位 比如:CMP,CMN,TST,TEQ 数据传送指令 指令 描述 MOV{条件}{S}目的寄存器,操作数 数据传送指令 MVN{条件}{S}目的寄存器,操作数 数据取反传送指令 {S}选项决定指令的操作是否影响CPSR中条件标志位的值 MVN与MOV不同之处是在传送之前按位被取反 __asm__ ("mov ri,r0“); //将寄存器R0的值传送到寄存器R1 __asm__(”mov r1,r0,lsl#3"); //将寄存器R0的值左移3位后传到R1 __asm__(“mov pc,lr"); //将寄存器lr的值传送到pc,常用于子程序返回 __asm__("mvn r0,#0”); // 将立即数0 取反传送到寄存器R0中,完成后R0=-1 比较指令 指令 描述 CMP{条件}操作数1,操作数2 比较指令 CMN{条件}操作数1,操作数2 比较反值指令 TST{条件...