• 汇编语言间接寻址

    直接寻址很少用于数组处理,因为,用常数偏移量来寻址多个数组元素时,直接寻址不实用。反之,会用寄存器作为指针(称为间接寻址)并控制该寄存器的值。如果一个操作数使用的是间接寻址,就称之为间接操作数。

    间接操作数

    保护模式

    任何一个 32 位通用寄存器(EAX、EBX、ECX、EDX、ESI、EDI、EBP 和 ESP)加上括号就能构成一个间接操作数。

    寄存器中存放的是数据的地址。示例如下,ESI 存放的是 byteVal 的偏移量,MOV 指令使用间接操作数作为源操作数,解析 ESI 中的偏移量,并将一个字节送入 AL:

    .data
    byteVal BYTE 10h
    .code
    mov esi,OFFSET byteVal
    mov al,[esi]                              ; AL = 10h

    如果目的操作数也是间接操作数,那么新值将存入由寄存器提供地址的内存位置。在下面的例子中,BL 寄存器的内容复制到 ESI 寻址的内存地址中:

    mov [esi],bl

    PTR 与间接操作数一起使用

    一个操作数的大小可能无法从指令中直接看出来。下面的指令会导致汇编器产生“operand must have size(操作数必须有大小)”的错误信息:

    inc [esi]    ;错误:operand must have size

    汇编器不知道 ESI 指针的类型是字节、字、双字,还是其他的类型。而 PTR 运算符则可以确定操作数的大小类型:

    inc BYTE PTR [esi]

    数组

    间接操作数是步进遍历数组的理想工具。下例中,arrayB 有 3 个字节,随着 ESI 不断加 1,它就能顺序指向每一个字节:

    .data
    arrayB BYTE 10h,20h,30h
    .code
    mov esi,OFFSET arrayB
    mov alz [esi]                        ;AL = lOh
    inc esi
    mov al, [esi]                        ;AL = 20h
    inc esi
    mov al, [esi]                        ;AL = 30h

    如果数组是 16 位整数类型,则 ESI 加 2 就可以顺序寻址每个数组元素:

    .data
    arrayW WORD 1000h,2000h,3000h
    .code
    mov esi,OFFSET arrayW
    mov ax,[esi]                         ; AX = 1000h
    add esi, 2
    mov ax,[esi]                         ; AX = 2000h
    add esi, 2
    mov axz [esi]                        ; AX = 3000h

    假设 arrayW 的偏移量为 10200h,下图展示的是 ESI 初始值相对数组数据的位置。

更多...

加载中...