0

Cと混合すると機能するasmコードに問題がありますが、適切なパラメーターを使用してasmコードで使用すると機能しません。

;; array - RDI, x- RSI, y- RDX
getValue:   
   mov r13, rsi
   sal r13, $3
   mov r14, rdx
   sal r14, $2
   mov r15, [rdi+r13]
   mov rax, [r15+r14]

   ret

技術的には、rdi、rsi、およびrdxレジスタをそのままにしておきたいので、他のレジスタを使用します。

x64マシンを使用しているため、ポインターのバイト数は8バイトです。技術的に言えば、このコードは次のことを行うことになっています。

int getValue(int** array, int x, int y) {
    return array[x][y];
}

それはどういうわけか私のCコード内で機能しますが、このようにasmで使用された場合は機能しません。

mov rdi, [rdi]    ;; get first pointer - first row
mov r9,  $4       ;; we want second element from the row
mov rax, [rdi+r9] ;; get the element (4 bytes vs 8 bytes???)
mov rdi, FMT      ;; prepare printf format "%d", 10, 0
mov rsi, rax      ;; we want to print the element we just fetched
mov eax, $0       ;; say we have no non-integer argument
call printf       ;; always gives 0, no matter what's in the matrix

誰かがこれを調べて私を助けることができますか?前もって感謝します。

4

2 に答える 2

1

sal r14, $2要素がdwordsであることを意味するため、前の最後の行はretqwordをロードしないでください。さらに、x86には優れたスケーリングアドレッシングモードがあるため、次のことができます。

mov rax, [rdi + rsi * 8]  ; load pointer to column
mov eax, [rax + rdx * 4]  ; note this loads a dword
ret

これは、列へのポインタの配列があることを意味しますが、これは珍しいことです。あなたはそれをすることができます、しかしそれは意図されていましたか?

于 2013-03-24T16:27:45.733 に答える
0

これは整数の標準行列です。

int** array;
sizeof(int*) == 8
sizeof(int) == 4

私が最初にその配列を持っているとき、私はすべてのポインタを1つずつ(インデックスごとに)保持する「空白」のないメモリのスペースへのポインタを持っているので、「配列の要素rsi-th」であるため、rsi-th*8バイトだけシフトします。だから今私は同じ状況になりますが、ポインタは整数のスペースを指しているはずなので、4バイトのアイテムです。そのため、そこで4バイトシフトします。

私の考えは間違っていますか?

于 2013-03-24T16:24:11.097 に答える