我需要一些有关汇编语言矩阵运算的帮助。 我的代码在 C 和 ASM 中进行 Cholesky 分解并比较它们的速度。 我已经创建了嵌套循环并且它工作正常,是的我不知道如何正确处理矩阵以访问其元素。矩阵在 C 中是 DOUBLE,我设法将其地址(第一个元素)传输到程序集。
Cholesky_double proc \
tab_addr:DWORD, \ ; begin adres of matrix
num_elem:DWORD ; element count in row/column (n of Matrix[n][n])
LOCAL i:DWORD, k:DWORD, j:DWORD, skoczek:DWORD
;skoczek is for operation count check (ex.should be 13 for 3x3 matrix)
; push register on stack
push edx
push ecx
push ebx
push esi
push edi
mov k, 0
mov skoczek, 0
for0start:
inc skoczek
mov eax, k
mov i, eax
inc i
;there should be MATRIX[k][k] = sqrt(MATRIX[k][k])
mov eax, num_elem
sub eax, i
cmp eax, 0
je for1end
for1start:
inc skoczek
;MATRIX[i][k]=MATRIX[i][k]/MATRIX[k][k]
for1koniec:
inc i
mov eax, num_elem
sub eax, i
cmp eax, 0
jne for1start
for1END:
mov eax, k
mov j, eax
inc j
mov eax, num_elem
sub eax, j
cmp eax, 0
je for2end
for2start:
inc skoczek
mov eax, j
mov i, eax
for3start:
inc skoczek
;MATRIX[i][j] = MATRIX[i][j]-MATRIX[i][k]*MATRIX[j][k]
for3koniec:
inc i
mov eax, num_elem
sub eax, i
cmp eax, 0
jne for3start
for2koniec:
inc j
mov eax, num_elem
sub eax, j
cmp eax, 0
jne for2start
for2end:
for0koniec:
inc k
mov eax, num_elem
sub eax, k
cmp eax, 0
jne for0start
koniec:
pop edi
pop esi
pop ebx
pop ecx
pop edx
mov eax, skoczek
ret
; return with operation count in eax
Cholesky_double endp
在 C 中传递的矩阵
extern "C" int __stdcall Cholesky_double(double* tab_adr, int num_el);
我使用 Visual Studio 2010 和解决方案来创建 ASSEMBLY 库的项目,以及使用可以使用汇编器函数的 C++ 代码的项目。
我并不是要求为我填写代码,只是为了正确寻址矩阵以正确访问其元素提供一点帮助。如果您预见到这里会出现更多问题(例如 asm 中的 Sqrt),我将很高兴获得一些指导。
最佳答案
您首先必须线性化地址:
&matrix[k][i] = matrix + i*sizeof(double) + k*N*sizeof(double);
其中 N 是行宽。 (假设NxN矩阵)
可以加载
fld [%eax] // load to top of stack in FPU (assuming ia-32 system)
mov %rbx,[%rax]; // vs. load 64-bit register
movsd %xmm0, [%rax] // vs. load a double to lower 64-bits of xmm register
关于c - double 型矩阵 [n]x[n] 传输至 ASSEMBLY,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15199443/