装配寻址模式

时间:2012-11-27 10:09:53

标签: arrays assembly matrix memory-address addressing-mode

这是代码:

section .data
v dw 4, 6, 8, 12
len equ 4
section .text
    global main
main:
    mov eax, 0 ;this is i
    mov ebx, 0 ;this is j
cycle:
    cmp eax, 2 ;i < len/2
    jge exit
    mov ebx, 0
    jmp inner_cycle
continue:
    inc eax
    jmp cycle
inner_cycle:
    cmp ebx, 2
    jge continue
    mov di, [v + eax * 2 * 2 + ebx * 2]
    inc ebx
    jmp inner_cycle
exit:
    push dword 0
    mov eax, 0
    sub esp, 4
    int 0x80

我正在使用一个数组并将其作为矩阵扫描,这是上述代码的C转换

int m[4] = {1,2,3,4};
for(i = 0; i < 2; i++){
    for(j = 0; j < 2; j++){
        printf("%d\n", m[i*2 + j]);
    }
}

当我尝试编译汇编代码时,我收到此错误:

DoubleForMatrix.asm:20: error: beroset-p-592-invalid effective address

指的是这一行

mov di, [v + eax * 2 * 2 + ebx * 2]

有人可以解释一下这条线有什么问题吗?我认为这是因为寄存器尺寸,我尝试了

mov edi, [v + eax * 2 * 2 + ebx * 2]

但我也遇到了同样的错误。

这是适用于Mac OS X的程序集,要使其在另一个上运行,您必须更改退出系统调用。

2 个答案:

答案 0 :(得分:1)

SIB (Scale Immediate Base)寻址模式只需要将一个Scale参数(1,2,4或8)应用于一个寄存器。

建议的解决方案是将eax预乘4(也必须修改比较)。然后,inc eax可以替换为add eax,4,非mov di,[v+eax+ebx*2]

更高级别的优化仅针对for (i=0;i<4;i++) printf("%d\n",m[i]);

答案 1 :(得分:1)

您不能在汇编程序中使用任意表达式。只允许几个寻址模式。

基本上最复杂的形式是register / imm + register * scale with scale 1,2,4,8

当然,常数(如2 * 2)可能会折叠为4,因此计为单个刻度,为4(不是两次乘法)

你的例子试图一次做两次乘法。

解决方案:插入额外的LEA指令来计算v + ebx * 2并在mov中使用结果。

     lea regx , [v+ebx*2]
     mov edi, [eax*2*2+regx]

其中regx是免费注册。

相关问题