CでAVX行列 - ベクトル乗算関数を書いていましたが、必要な命令がGCCに実装されていないことが分かったので、いくつかのx86アセンブリを学ぶ絶好の機会でした。私は最初にMIPSアセンブリでルーチンを書いてから翻訳を試みました。私のコードは機能しません、私はsegfaultを取得し、私は理由を知りません。コード内の2つのjnz
を削除すると機能しますが、なぜ影響を受けるのか分かりません。このタイプのジャンプは私が使用しているレジスタを破壊しますか?NASM行列 - ベクトル乗算
EDIT:main
の最初の2つの命令は、rdi
を2に設定せず、むしろ後で問題を引き起こす0x1000000002
に設定されているようです。 2がロードされないのはなぜですか?
EDIT2:入手しました。 @rkhbが指摘するように、rXXレジスタを使用すると、意図したより多くのデータがロードされます。私はレジスタを32ビットのレジスタに変更しました(適用可能な場合)。これはsegfaultの問題を解決しました。しかし今、プログラムは0,0を印刷しました。これはループがeaxを8進めるため(以下の例では)、返す前にその量を減算しないためです。したがって、値はaddr
とaddr+4
ですが、返されるポインタはaddr+8
です。
; nasm -felf64 filename.asm
; gcc filename.o
global main
extern printf
section .data
N: dd 2 ; dimension
a: dd 1, 2, 3, 4 ; matrix
b: dd 1, 2 ; vector
format: db "%d", 10, 0
section .bss
c: resb 8 ; reserve 8B
section .text
main:
; set up arguments
lea rdi, [N] ; fix: change regs to edi, etc
mov rdi, [rdi]
lea rsi, [a]
lea rdx, [b]
lea rcx, [c]
call matvec ; c = a*b
; print results
mov rsi, [rax]
mov rdi, format
push rax
mov rax, 0
call printf ; print c[0], should be 5
pop rax
add rax, 4
mov rsi, [rax]
mov rdi, format
mov rax, 0
call printf ; print c[1], should be 11
ret
; rdi = N, rsi = int*, rdx = int*, rcx = int*
matvec:
mov rax, rcx ; rax = c
mov R14, rdi ; r14 = N
mov R15, R14
shl R15, 2 ; r15 = 4*N
xor R8, R8 ; i = 0
xor R9, R9 ; j = 0
xor R10, R10 ; sum = 0
loop:
mov R11, [rsi] ; r11 = *a
mov R12, [rdx] ; r12 = *b
imul R11, R12 ; r11 *= r12
add R10, R11 ; r10 += r11
add rsi, 4 ; a++
add rdx, 4 ; b++
add R9, 1 ; j++
cmp R14, R9
jnz loop ; loop while r14-r9 = N-j != 0
mov [rax], R10 ; *c = sum
xor R10, R10 ; sum = 0
xor R9, R9 ; j = 0 on every i loop
sub rdx, R15 ; b -= 4*N
add rax, 4 ; c++
add R8, 1 ; i++
cmp R14, R8
jnz loop ; loop while r14-r8 = N-i != 0
sub rax, R15 ; fix: subtract 4*N from return pointer
ret
'mov rdi、[rdi]'は8バイトをロードします。しかし、「N:dd 2」はわずか4バイトです。 'dd'を' dq'に変更してください。 – rkhb
ありがとうございます。私はそれが何かを持っているかもしれないと思ったので、私はより面倒な変更を加えました。つまり、すべてのregをraxからeaxなどに変更しました。今は動作しますが、mainに戻った後、raxの値はゼロになります。 toは0になります。 –
問題を解決した場合は、質問の編集ではなく、回答として投稿する必要があります。 –