armv8汇编码分析

发布于:2025-07-03 ⋅ 阅读:(14) ⋅ 点赞:(0)

arm 为 RISC ,指令长度定长为4字节

bit[25,28]  4bit为操作类型码,含义如下:

image.png

以第一个Data Processing -- Immediate (立即数数据处理)为例 ,bit[23,25]表示指令码,具体含义如下

image.png

以move指令为例  即bit [23,25] 为101 ,bit[23,28] 为100 101;

mov指令分为如下几类,有根据opc bit[29,30] 和 sf bit[31]来表示不同的mov指令,以movz指令为例,即010 ,bit[23,31] 为010 100 101

image.png

MOVZ  sf指令 0/1 都是movz,sf指令代表 寄存器是32 bit还是64bit 0:32bit,1:64bit

image.png

32-bit variant

Applies when sf == 0.

MOVZ <Wd>, #<imm>{, LSL #<shift>}

64-bit variant

Applies when sf == 1.

MOVZ <Xd>, #<imm>{, LSL #<shift>}

Decode for all variants of this encoding

 integer d = UInt(Rd); 

 integer datasize = if sf == '1' then 64 else 32; 

 integer pos; 

 if sf == '0' && hw<1> == '1' then UnallocatedEncoding(); 

 pos = UInt(hw:'0000');  //表示hw 后追加4bit 0,也就是说hw为01, pos为010000;

Operation

 bits(datasize) result; 

 result = Zeros(); 

 result<pos+15:pos> = imm16; 

X[d] = result; 

MOVK MOVZ MOVN区别

image.png

对于立即数的指令选取

由上文知arm v8对于 立即数有限制,只能用16bit来存储立即数,可通过移位和取反操作来覆盖更多的立即数,只有覆盖不到的就会通过两条指令来完成赋值

MOVZ:  

image.png

MOVN:

image.png

立即数范围 指令 指令码 备注

高四16进制位全0:i

{i取值 [0-0xffff]}

movz w0,#0x1

0x52800020

0x529

hw位bit[21,22]为00b,表示不左移,bit[5,20] 为1,所以就是拷贝的 1

低四16进制位全0:(0xi0000 & 0xFFFF0000)

{i取值 [1-0xffff]}

movz w0,#0xfff

f0000

0x52bfffe0

0x52a

hw位bit[21,22]为01b,表示左移16bit,bit[5,20] 为0xffff,所以就是拷贝的 0xffff << 16 0xffff0000

高四16进制位全F:(0xi | 0xFFFF0000)

{i取值 [1-0xffff]}

mov  w0, #0xffffffff

0x12800000

0x129

hw位bit[21,22]为00b,表示不左移,bit[5,20] 为0,所以就是拷贝的

  ~(0 ) = 0xffffffff

低四16进制位全F:(0xi0000 | 0xFFFF)

{i取值 [1-0xfffe]}

movn w0,#0x1ffff

0x12bfffc0

0x12a

hw位bit[21,22]为01b,表示左移16bit,bit[5,20] 为0xfffe,所以就是拷贝的

  ~(0xfffe<< 16 ) = ~0xfffe0000 = 0x1ffff;

/* 当前接口仅支持大端armv8 ,其余未验证 */
UINT32 will_return_to_arm_asm(int iData, unsigned char *pcAsm)
{
    int iDataTmp = 0;
    UCHAR *pcRetAsm = NULL;
    /* ARM机器码的阅读和在内存中的存储是相反的 */
    /*将函数代码段替换为以下内容,实现直接修改函数返回值*/
    /* 52800140        mov     w0, #0xa   // #10
    d65f03c0        ret                  */
    Bsp_Printf("iData:0x%x\n", iData);
    pcRetAsm = &(pcAsm[8]);
    ARM_RET_CMD(pcRetAsm);
    /* 高16位全0 1: 0x52800020 */
    if (0 == (iData & 0xFFFF0000))
    {
        Bsp_Printf("1: iData:0x%x\n", iData);
        pcAsm[0] = (iData << 5) & 0xFF;
        pcAsm[1] = (iData >> 3) & 0xFF;
        pcAsm[2] = (iData >> 11) | 0x80;
        pcAsm[3] = ARM_MOVZ_CMD;
    }
    /* 低16位全0 0x10000 : 0x52b00020        */
    else if (0 == (iData & 0xFFFF))
    {
        iDataTmp = (iData >> 16) & 0xFFFF;//右移16
        Bsp_Printf("2: iDataTmp:0x%x\n", iDataTmp);
        pcAsm[0] = (iDataTmp << 5) & 0xFF;
        pcAsm[1] = (iDataTmp >> 3) & 0xFF;
        pcAsm[2] = (iDataTmp >> 11) | 0xA0;//左移16
        pcAsm[3] = ARM_MOVZ_CMD;
    }
    /* 高16位全1 */
    else if (0xFFFF0000 == (iData & 0xFFFF0000))
    {
        iDataTmp = ~iData;//按位取反
        Bsp_Printf("3: iDataTmp:0x%x\n", iDataTmp);
        pcAsm[0] = (iDataTmp << 5) & 0xFF;
        pcAsm[1] = (iDataTmp >> 3) & 0xFF;
        pcAsm[2] = (iDataTmp >> 11) | 0x80;
        pcAsm[3] = ARM_MOVN_CMD;
    }
    /* 低16位全1 */
    else if (0xFFFF == (iData & 0xFFFF))
    {
        iDataTmp = ((~iData) >> 16) & 0xFFFF;//按位取反,右移16
        Bsp_Printf("4: iDataTmp:0x%x\n", iDataTmp);
        pcAsm[0] = (iDataTmp << 5) & 0xFF;
        pcAsm[1] = (iDataTmp >> 3) & 0xFF;
        pcAsm[2] = (iDataTmp >> 11) | 0xA0;//左移16
        pcAsm[3] = ARM_MOVN_CMD;
    }
    else
    {
        Bsp_Printf("no support ! iData:0x%x\n", iData);
        return BSP_ERROR;
    }

    return BSP_OK;
}

总结:ARM V8能用单条指令来进行赋值操作的立即数 需要是以下四种:

高四16进制位为全0/全F ;低四16进制位全0/全F 

DDI0487B_armv8_20170925.pdf

分析发现无法支持非法立即数的返回操作,能否把所有数据都按照4条指令来完成赋值,如下图 立即数:0x1234567890123456 (64bit)

image.png

movk 与movz区别是,movz会清除其它位,movk保留

image.png

image.png

需要考虑修改20字节的话会不会操作到其它函数,也就是说被打桩函数大小需要超过5条指令,反汇编发现只有一个retrun 的函数,指令也是 12条

image.png

image.png

还需要考虑进修改此页能不能包含20字节修改,否则会失败,如下图,当修改函数CmdkBttlReparserHwCntGet 时

因为CmdkBttlReparserHwCntGet 函数地址位0xffff7cc0dff4  + 20 =  0xFFFF7CC0E008  超过了 0xFFFF7CC0D000 0xFFFF7CC0DFFF 这个页范围,需要修改两个页的内存属性

image.png

修改后:

image.png

image.png


网站公告

今日签到

点亮在社区的每一天
去签到