ARM汇编笔记

3 篇文章 0 订阅
2 篇文章 0 订阅

简介

现阶段ARM已存在64位体系架构即armv8,指令体系分为:AARCH_64和AARCH_32
Armv7a以及之前的架构使用的arm指令称为A32(ARM)和T32(Thumb),armv8使用的64位指令成为A64,兼容32位(ABI级并不兼容,两种执行模型)

体系

处理器模式:
用户模式(User):ARM处理器正常的程序执行状态(相当于intelR3)
快速中断模式(FIQ):用于高速数据传输或通道处理
外部中断模式(IRQ):用于通用的中断处理
管理模式(Supervisor):操作系统使用的保护模式(相当于intelR0)
数据访问终止模式(Abort):当数据或指令预取终止时进入该模式,可用于虚拟存储及存储保护
系统模式(System):运行具有特权的操作系统任务
未定义指令中止模式(Undifined):当未定义的指令执行时进入该模式,可用于支持硬件协处理器的软件仿真

寄存器

R0-R7 通用寄存器,可任意使用
R8-R12 通用寄存器,在不同模式下含义有变化
SP(R13) 通常作为栈指针寄存器(x86esp)
LR(R14) 链接寄存器,保存返回点地址(返回值在另一专门寄存器)
PC(R15) 程序计数器,由于arm体系的流水线特点,实际执行地址为(PC + 2 * 指令大小),因为预取的
CPSR 当前程序状态寄存器,包含条件码和控制位。在一些模式下存在SPSR,用于备份CPSR(比如比较结果放在这)
注:arm存在little-endian和big-endian,绝大多数Android使用小端,后文均是小端模式

CPSR简介

CPSR 当前程序状态寄存器
条件标志
N – N == 1 表示执行为负
Z – Z == 1 表示执行为零
C – C == 1 表示执行进位
V – V == 1 表示执行溢出(有符号数)
控制位
I – IRQ 中断禁止标志
F – FIQ 快速中断标志
M[4:0] 模式执行
T – 状态指示 T == 1 Thumb模式,T == 0 ARM模式

所以条件标志是可以组合的。

条件标识

ARM分为ARM状态和Thumb状态,以CPSR T作为状态指示,执行不同的指令集
ARM指令集
指令固定4字节
包含条件码,有条件执行
能访问所有寄存器
THUMB指令集
T1指令2字节,T2指令4字节(因为早期处理器还有16位的)而且可以节省空间
仅分支指令存在条件执行(比如跳的时候待条件)
仅能访问R0-R7,SP,LR,PC()
PC寄存器值 = 当前地址 + 1,1可以理解为pC执行基地址时候,把1赋值给了thumb状态(就是开头)

注意arm不能直接内存值相加,比如x86可以esp+4,arm要把4先给要先给寄存器。寄存器操作,再把值给存回去覆盖。

另外THUMB指令

条件标识不是在头部,分为前后两个组。比如THUMB2是4字节。

THUMB2指令,固定4字节,分为前后2个字节,组成两组。

跳转指令

arm可以直接改pc值,比如 mov pc,r0

在 ARM 中有两种方式可以实现程序的跳转,一种是使用跳转指令直接跳转,另一种则是直接向 PC 寄存器赋值实现跳转。跳转指令有跳转指令 B,带链接的跳转指令 BL 带状态切换的跳转指令 BX。

因为arm总共才4字节,4GB跳转空间,不能跳整个空间。所以b跳转是根据pc的值,一般是循环,条件等。

bl label就是LR<-pc-2*指令大小(因为是arm)。返回地址是当前要执行指令的下一条指令。而当前PC实际是当前指令加上两条指令的大小。一般是函数调函数用到。

bx rm不是跳一个位置了,一般是函数指针,因为不知道目的在哪,先把跳转地址存到某个寄存器,然后去挑,x是状态切换,不知道目标是arm还是thumb状态。

LDM 和 STM 指令

这两个一般出现在函数头部,因为要存放零时变量。

LDM:Load from memory into register
LDMFD SP! , {R0, R1, R2}(!是要修改SP,不然就要两条指令,多一条操作sp降低栈指针)
把sp指向的3个连续地址段(应该是3*4=12字节(因为为r0,r1,r2都是32位))中的数据拷贝到r0,r1,r2这3个寄存器中去

STM:S的含义仍然是STORE,与LDM是配对使用
STMFD SP!, {R0}
把R0保存到堆栈(sp指向的地址)中
sp后面的!,作用是指命令执行完后,对应的地址值赋给sp,对于例程的SDM,是说最后sp的值应该是sp+3*4=sp+12

比如函数调用先STM把函数参数从寄存器存到栈上,返回就是LDM。一般栈指针从高地址到低地址。pc从小到大跟x86一样。

LDR 和 STR  指令

加载/存储字和无符号字节指令。使用单一数据传送指令(STR 和LDR)来装载和存储单一字节或字的数据从/到内存。LDR 指令用 于从内存中读取数据放入寄存器中;STR 指令用于将寄存器中的数据保存到内存。

LDR指令的格式: 
LDR{条件}  目的寄存器, <存储器地址>
作用:将 存储器地址 所指地址处连续的4个字节(1个字)的数据传送到目的寄存器中。
STR指令的格式为:
STR{条件}  源寄存器, <存储器地址>
STR指令用亍从源寄存器中将一个字数据传送到存储器中。

eg:
(1)ldr R0, [R1, #8]   将地址R1 + 8的字数据读入以R0存储器中
(2)ldr R0, [R1], #8 将R1的数据读入到R0,并将R1 + 8的值存入R1

(1)str R0, [R1, #8]   将R0中的字数据读入以R1 + 8为地址的存储器中
这里就是说R1的地址为0x00001000,R0装的是0x00aa,将0x00aa装入0x00001000 + 8的地址里,也就是0x00001008地址
(2)str R0, [R1], #8   将R0的字数据读入R1,并将R1 + 8的值存入R1,也就是把R1的等于
这里我还是解释一下,将R0的字数据读入的是以R1中数据为地址的存储器中,比如r1中装的是0x00001000,R0是0x00aa,通俗的说就是把0x00aa读入以0x0001000的地址里面。

arm函数调用约定

ARM CPU有16个寄存器:r0到r15。每个寄存器为32bit。调用约定规定了这些寄存器的特定用途。如下:
r0 – r3:存储传递给函数的参数值,多余的参数通过压栈传递!
r4 – r11:存储函数的局部变量,Thumb模式不会使用r8以后的寄存器
r12:是内部过程调用暂时寄存器(intra-procedure-call scratch register)。
r13:存储栈指针(sp)。在计算机中,栈非常重要。这个寄存器保存着栈顶的指针。这里可以看到更多关于栈的信息。
r14:链接寄存器(link register)。存储着当被调用函数返回时,将要执行的下一条指令的地址。
r15:用作程序计数器(program counter)。存储着当前执行指令的地址。每条执行被执行后,该计数器会进行自增(+1)。

函数的返回值放到r0中。
当我们查看刚进入函数的时候:
pc总是包含下一个要被执行的指令的位置。
arm7采用三级流水
(1)取指(fetch)
取指级的任务是从程序存储器中读取指令。
(2)译码(decode)
译码级完成对指令的分析,并为下一个周期准备数据路径需要的控制信号。在这一级,指令占用译码逻辑,不占用数据通路。
(3)执行(excute)
完成指令要求的操作,并根据需要将结果写回寄存器。指令占用数据路径,寄存器堆被读取,操作数在桶行移位器中被移位。运算器产生运算结果并回写到目的寄存器中,运算器根据指令需求和运输结果更改状态寄存器的条件位
arm7中执行和取指是隔了一级译码级,那一级不读取数据,当前PC=原PC+2 * sizeof(inst_size)所以链接寄存器保存的是下一条指令真实的PC减去一条指令的大小。
lr (总是)包含函数返回时要装载的地址。

所以arm与smali区别:一个直接cpu执行,一个解释执行。一个借助真实CPU,一个纯寄存器。smali需要显示的把函数结果拿到。

ARM(aarch64)

因为armv8前设计根本没考虑虚拟化等,设计的就不好,armv8就改进了设计。

这里EL0级别最低。比如一个程序指纹识别,程序在applicaton,发消息给内核驱动GuestOS,(Hypervisor一般手机可能没有,先忽略)Secure monitor让处理器在这里进行NormalWorld和SecureWorld切换,信息转到了Secure world,Trusted OS类似Linuxkernel,前面来的请求一般放在EL0,在SecureWorld也要专门处理前面比如指纹识别的TRUSEAPPLICATION。然后再跟TrustedOS进行交互,

Normal world和Secure world内存在物理上隔离的,通过secure monitor管理。

ARMv8硬件缓解机制

PXN - Privileged Execute Never
V8.0 - 对抗EL1执行EL0恶意代码,不能在内核直接跳到用户层执行代码。
PAN - Privileged Access Never
V8.1 - 对抗EL1直接访问EL0恶意数据,除了拷贝时机不给访问(比如在进行系统调用发一个请求进入内核,内核会做一个动作,把请求的数据拷贝到内核空间,除开拷贝没有其他动作,这样原来的漏洞解释内核的pc,用他执行代码,内核指针知道用户层然后操作,现在就不行了)

PAC - Pointer Authentication,保护的指针不能修改,指针是通过硬件算法算出的值,使用类似解密操作,所以越狱等操作就高了很多。
V8.3 – 硬件CFI,ELx均可使用

ARMv8a

处理器分为AArch64和AArch32执行模式
AArch32模式指令与ARMv7基本一致,模拟32位指令,一些具体不一样。
AArch64寄存器
X0-X30(w0-w30), X30即LR(因为是64位比如执行一个long数据就用x,int就用w,高位没用)
PC\SP_ELx\ELR_ELx(x = {0, 1, 2, 3})(不能直接操作PC,所以是x31)
PSTATE一组寄存器,包含类似CPSR信息(比如要进入内核,CPSR就存到栈上了)
XZR/WZR(X31)
数值处理: 读取为0,忽略写入
LOAD/STORE指令:表示SP值


指令特点

与AArch32指令不同, AArch64只有A64指令集
指令种类增多,仍然为定长4字节指令
条件标志与AArch32一致
PC即当前地址,与ARMv7a区别
不能直接访问PC寄存器(就是mov什么到PC)

调用约定

X0-X7参数传递(32位是r0到r3)
内核使用X8传入系统调用号,32位是r7

一些指令

STP和LDP指令

STP:Store Pair of Registers 
存放一对寄存器到指定地址
STP <Xt1>, <Xt2>, [<Xn|SP>], #<imm> (!)

 

这里opc的x0这些表示是32位还是64位,这里没用条件标志了。
 

B指令

这里B,B.cond是条件跳转范围不一样,BR激素因为这里不能直接操作PC,需要通过将地址放到寄存器,然后跳过去。

BLR是带链接的跳转,将吓一跳指令放到LR这里是PC+4,没那么复杂了。

特权指令

比如从架构不同层跳转,guestos到Hypervisor

SVC 特权模式EL1,HVC 特权模式EL2,SMC特权模式EL3,不能从0直接到下面。

 

 

 


 

 

 

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
汇编语言可以在ARM架构中实现冒泡排序算法。首先,我们可以使用汇编语言编写一个函数来实现冒泡排序。这个函数可以接受一个字符数组和数组的长度作为参数。然后,我们可以通过使用汇编指令来执行冒泡排序的步骤。 首先,我们可以使用str指令来交换数组中相邻的元素。为了实现冒泡排序,我们需要一个内部循环来比较和交换相邻的元素,直到数组被完全排序。我们可以使用cmp指令来控制内部循环的次数。然后,我们可以使用bne指令来跳转到内部循环的开始,直到数组被完全排序。 同时,我们还需要一个外部循环来控制整个排序的次数。我们可以使用cmp指令来控制外部循环的次数。然后,我们可以使用bne指令来跳转到外部循环的开始,直到数组被完全排序。 为了实现这个汇编程序,我们可以参考提供的C语言与汇编语言混合使用的代码。通过仿照C语言的代码流程,我们可以分步骤编写汇编代码。首先,我们需要编写交换数据的汇编代码。然后,我们需要考虑内部循环的代码,以及外部循环的代码。 总之,使用ARM汇编语言实现冒泡排序需要编写交换数据的汇编代码,并通过内部循环和外部循环来实现排序算法。你可以参考提供的C语言与汇编语言混合使用的代码,并根据这个代码来编写你的汇编程序。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [【ARM学习笔记】C与汇编混合编程—冒泡排序算法](https://blog.csdn.net/qq_43401552/article/details/105686643)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] - *2* *3* [ARM C语言调用汇编函数 实现冒泡排序](https://blog.csdn.net/ZHJ123CSDN/article/details/105511944)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值