博客> 逆向3-CPU&寄存器
逆向3-CPU&寄存器
1小时前 评论:0 阅读:248 BellaWong
进制 CPU

 1.png

寄存器

  • CPU中最主要部件是寄存器,可以通过改变寄存器的内容来实现对CPU的控制
  • 不同的CPU,寄存器的个数、结构是不相同的

寄存器的作用:数据临时存储

通用寄存器

64位: X0-X30, XZR(零寄存器)

32位: W0-W30, WZR(零寄存器)

  • ARM64拥有有31个64位的通用寄存器X0 - X30
  • 这些寄存器通常用来存放一般性的数据(有时也有特定用途)
  • 通常,CPU会先将内存中的数据存储到通用寄存器中,然后再对通用寄存器中的数据进行运算
  • 对于arm64系的CPU来说, 如果寄存器以x开头则表明的是一个64位的寄存器,如果以w开头则表明是一个32位的寄存器,为了兼容32

 5.png

特殊寄存器:
  • sp寄存器:在任意时刻会保存我们栈顶的地址,sp指向哪里,哪里就是栈(唯一的一个判断栈标识)
  • fp寄存器:也称为x29寄存器属于通用寄存器,但是在某些时刻我们利用 保存栈底的地址

fp在ARM64中显得比较鸡肋,以前做push和pop操作的时候,进行压栈操作,需要对sp原来的值进行保护,通过fp进行保护。但为了兼容32位,fp还留着

  • pc寄存器:为指令指针寄存器,它指示了当前要读取指令的地址

 6.png

tips:ARM64开始,取消32位的 LDM,STM,PUSH,POP指令! 取而代之的是ldr\ldp str\stp ARM64里面 对栈的操作是16字节对齐的!!

假设内存中有块红色内存空间的值是3,现在想把它的值加1,并将结果存储到蓝色内存空间  2.png

  1. CPU首先会将红色内存空间的值放到X0寄存器中:mov X0,红色内存空间
  2. 然后让X0寄存器与1相加:add X0,1
  3. 最后将值赋值给内存空间:mov 蓝色内存空间,X0

每次运算完之后,又开辟新的内存空间存放结果? 答:在汇编里,不存在开辟空间,销毁空间,直接通过内存地址访问

问题:将w0改了,X0为什么也改了: 答:w0是x0的低32位,w开头的寄存器并没有独立存储在CPU中,是x开头的寄存器的低32位,如果改了x寄存器的低32位,那么x寄存器必然修改了

浮点和向量寄存器

因为浮点数的存储以及其运算的特殊性,CPU中专门提供浮点数寄存器来处理浮点数

现在的CPU支持向量运算.(向量运算在图形处理相关的领域用得非常的多)为了支持向量计算系统了也提供了众多的向量寄存器.

  • 浮点寄存器 64位: D0 - D31 32位: S0 - S31
  • 向量寄存器 128位:V0-V31

tips:之前讲解8086汇编中有一种特殊的寄存器段寄存器:CS,DS,SS,ES四个寄存器来保存这些段的基地址,这个属于Intel架构CPU中.在ARM中并没有

Xcode下方Debug area 将auto选项改为All就可以看到各种寄存器 tips:模拟器是x86架构,和真机的寄存器不一样

 3.png

 4.png

高速缓存:

iPhone X 搭载的ARM处理器的一级缓存的容量是64KB,二级缓存容量是8M.

寄存器的运算速度远远超过内存的读写速度,在CPU中对数据进行运算,读一条,运行一条。从内存读取数据会相对缓慢一些,所以内存读取的速度就决定了CPU的运行速度,就形成了短板。所以就有了高速缓存的存在。

当程序在运行时,先将要执行的指令代码以及数据复制到高速缓存中去(由操作系统完成)。CPU直接从高速缓存依次读取指令来执行。

问题1:

既然高速缓存那么牛掰,为啥不把容量搞大点,能把所有的数据全部加载进去? 答:运行速度越快,做工选材越精良,成本越高。商业化的东西需要节约成本。

问题2:

pc 指向内存的哪里,cpu就执行哪条指令?没有看到告诉缓存的地址? 答:系统将数据保存到高速缓存之后,还会建立一个内存地址到高速缓存的一一对应的映射。所有pc 所指向的内存地址,其实是指向了高速缓存。

如果pc指向的地址在高速缓存中找不到,那么操作系统又会copy一份到高速缓存中。

栈:一种具有特殊访问方式的存储空间

存放函数的局部变量、参数、寄存器的保护

出了函数的大括号之后,局部变量没法用了,因为栈平衡了(sp加回去)

SP和FP寄存器:

ARM64开始,取消了32位的PUSH、POP指令(但栈的空间还是有的,通过SP偏移来放东西),取而代之的是ldr\ldp str\stp sp指向哪里,哪里就是栈(唯一的一个判断栈标识)

  • fp寄存器也称为x29寄存器,属于通用寄存器,但在某些时候我们利用它来保存栈底的地址
  • 内存读写指令 内存读写是往高地址读写,栈的操作往低地址操作

sp寄存器在任意时刻会保存我们栈顶的地址. fp在ARM64中显得比较鸡肋,以前做push和pop操作的时候,进行压栈操作,需要对sp原来的值进行保护,通过fp进行保护。但为了兼容32位,fp还留着

栈指令

  • str(store register):将数据从寄存器中读出来,存到内存中(写入内存)
  • ldr(load register):将数据从内存中读出来,存到寄存器中(读内存)
  • ldp和stp为str和ldr的变种指令。可以同时操作两个寄存器

怎么拿到栈空间:

通过挪动SP寄存器,SP当前所指向的是上一个程序调用所指向的地方,我们需要用的话,将SP挪动

栈是往低地址扩展的,堆是往高地址扩展

堆栈溢出:stack overflow 就是堆和栈碰一起,就是所谓的堆栈溢出

收藏
1
sina weixin mail 回到顶部