“ 前言:初学逆向 请多多指教”
学习到的内容
—
1、ARM的指令集机器编码格式
2、ARM的指令集指令格式
3、Arm的寻址方式
ARM的指令集机器编码格式
—
条件码:占4位,是最高执行的,它是条件执行的标志,相关的操作条件码如下:
指令码:占8位,也就是opcode
目的寄存器:占4位,那么最大的数也就是2^4次,一共代表了R0-R15寄存器
操作数1寄存器:占4位,那么最大的数也就是2^4次,一共代表了R0-R15寄存器
操作数2:占12位 ,那么最大的数最大也就是2^12次
知识点:所有的arm程序启动,必须都要从arm指令集开始,进入异常转换为ARM状态,运行ARM指令集指令
所以可以看出一条ARM指令的长度永远都是只占4个字节
ARM的指令集指令格式
—
在程序中编码的ARM指令格式如下:
1、{}包含的代表可有可无
2、带S后缀的条件指令会影响CPSR(标志寄存器),会影响条件码的跳转判断
这里举个例子:设置r1的值为1,然后运行如下指令:
subs r0,r1,#1
此时的Z标志寄存器的值会是0,此时是BEQ指令(这里的B是跳转指令)的话则会根据Z的标志寄存器的值来进行判断是否跳转,则影响跳转的就是依靠subs的结果是否为0
ARM的寻址方式
—
这里先讲立即寻址:
注意:
1、当立即数在操作数2中出现的时候,需要注意只能放置12位,不能直接进行32位的立即数赋值,但是也可以通过如下方法转换获得32位的立即数:
对下面的一条ARM指令进行格式分析:
机器码:E3A00CF2
MOV R0,#0x0000F200
E:最高执行的位是条件执行的标志,这里的E的二进制位是1110 则为AL 代表无条件
A3:代表mov指令
00:代表R0寄存器
C:循环右移值
2F:操作数2寄存器中的立即数0x2F,通过0xCF2 12位编码换算最终32位立即数为0xF200
那么最终结果就是R0寄存器保存了一个立即数为0xF200
根据上面解决方法,那么也就是每次进行立即数赋值的时候还需要进行判断的步骤,有没有办法可以不用判断?
可以通过ldr指令,比如如下ldr指令:
ldr r1=0x12345678
结果:ldr指令直接将立即数0x12345678赋值给了r1的寄存器
继续讲关于寄存器寻址:
1、这里需要知道的,在寻址的时候还可以对第二操作数寄存器先进行移位操作然后进行赋值
继续讲关于间接寻址:
在间接寻址中最基础的两个指令,如下图所展示:
后变址和前变址的寄存器寻址的不同点:
前变址:基地址加上偏移量的地址取值 然后进行赋值
前变址:基地址取值 然后进行赋值 再将基地址自增4个字节
回顾总结:其实跟win32汇编很相似,一个基地址 + 偏移地址来进行寻址,在win32中一般偏移地址都是edi esi 立即数来展现!