自己的反汇编引擎

本文介绍了386处理器引入的SIB(基址+标量索引)寻址方式,如何简化多维数组和结构体数组的内存操作。通过SIB字节的8bit结构,包括Scal、Index和Base的编码,以及它们与ModR/M、Displacement的关系。此外,还分享了利用SIB进行指令优化的汇编小技巧,如使用LEA指令和避免整数乘法。最后,提到了SIB解析代码的相关内容。
摘要由CSDN通过智能技术生成

第六部分 SIB

    386以前16位寻址模式下,要想操作一个多维数组或结构体数组是非常困难的,考虑下面的数组:

    Array2D  dword  Nrow dup (Ncol dup(?))
        
那么我们要想存取Array2D[rowIndex][colIndex],那么我们该怎么做呢?由于2维数组映射到内存中是一维的,那么Array2D[rowIndex][colIndex]的偏移地址就可以这么计算了:    Effect Address = BaseAddress + (rowIndex * colSize + colIndex) * ElementSize;
    
    
这里BaseAddress = Array2DcolSize = NcolElementSize = sizeof(dowrd) = 4;我们看看16位寻址模式下我们该如何获取该地址:

    mov  ax, Ncol
    mul rowIndex
    add ax, colIndex
    add ax, ax    ; () * ElementSize
,可用shl ax, 2代替
    add ax, ax          
    mov bx, ax          ; 16
位寻址模式下能用的只有基址寄存器和索引寄存器
    
    
这样dword ptr [bx]就是我们需要操作的对象了。当这个数组存储的是结构体的时候,可能还要用[bx + disp]的方式寻址到结构体内的成员。大家可以看到,简单的2维数组的操作就需要这么多指令,而当数组是3维或更大的维度的时候,这个过程的复杂程度还要增加。

    386
以后,除了寻址大小变成32位,寻址模式上有了很多的改进,所有的寄存器都参与寻址,是一个方面(至少可以省掉上面的一条指令)。最重要的Intel引入的新的寻址方式基址标量索引(SIB)寻址方式,这种寻址方式的引入大大简化了数组内存的存取过程。我们来看看什么是SIB寻址方式:
    
    [base + index * n + displacement]

    
这跟前面的[寄存器 + displacement]的寻址的一个重要的区别是多了一个Index * n,注意,这个部分是在指令执行的过程中运算的,跟一些在汇编期间进行的乘法运算有着本质的区别(例如[ebx + 标签常量 * 2]等)。这里的baseIndex8种通用寄存器中的任意一种。n的值不能是任意的,只能是248中的一个。在往下继续解释之前,我们看看上面的算法用32位寻址模式写可以怎么写:

    mov eax, Ncol
    mul rowIndex
    add eax, colIndex

    
这样dword ptr[eax * 4]就是我们要操作的对象了。当操作一维的结构体数组的时候,SIB的寻址模式将比传统的寻址模式有更大的优势。关于寻址模式和数组,结构体等的操作的例子和分析Art of assembly中的第四章和第五章有详细的介绍,给出这两章的下载:Ch04.pdf  Ch05.pdf

 6.1 SIB各个bit的涵义

    SIB的长度是固定的,只有一个字节,共8bit。我们从SIB寻址方式的定义中就可以大致推测出SIB的结构。
    
    [base + index * n + displacement]
n = 2, 4, 8displacement是后续字节

    base
index分别为8

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值