0

これはコードです:

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]

しかし、同じエラーが発生します。

これはMacOSXのアセンブリです。別のSOで動作させるには、exitsyscallを変更する必要があります。

4

2 に答える 2

1

SIB (Scale Immediate Base)アドレッシングモードでは、1つのスケール引数(1、2、4、または8)のみが1つのレジスタに適用されます。

提案された解決策は、eaxに4を事前に乗算することです(比較も変更する必要があります)。その後、とinc eaxに置き換えることができadd eax,4、違法な指示はmov di,[v+eax+ebx*2]

より高いレベルの最適化は、for (i=0;i<4;i++) printf("%d\n",m[i]);

于 2012-11-27T10:15:06.113 に答える
1

アセンブラで任意の式を使用することはできません。いくつかのアドレス指定モードのみが許可されます。

基本的に最も複雑な形式は、scale1,2,4,8のregister/ imm + register*scaleです。

もちろん、定数(2 * 2など)はおそらく4に折りたたまれるので、4の単一のスケールとしてカウントされます(2つの乗算としてではありません)

あなたの例では、一度に2つの乗算を実行しようとしています。

解決策:追加のLEA命令を挿入して、v + ebx * 2を計算し、その結果をmovで使用します。

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

ここで、regxはフリーレジスタです。

于 2012-11-27T10:20:09.107 に答える