Матрица двойного типа [n]x [n], переданная в сборку


Я хотел бы получить некоторую помощь в работе с матрицей на языке ассемблера. Мой код выполняет разложение Холецкого на C и ASM и сравнить их скорость. Я уже создал вложенные циклы, и он работает нормально, но я понятия не имею, как правильно обращаться к матрице, чтобы получить доступ к ее элементам. Матрица двойная в C, и мне удалось перенести ее адрес (первый элемент)в сборку.

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 и решение с проектом, который создает Библиотека сборок и проект с кодом на языке C++, который может использовать функции ассемблера.

Я не прошу заполнить код для меня, просто немного помочь с правильным адресованием матрицы, чтобы правильно получить доступ к ее элементам. Если вы предвидите больше проблем, приходящих сюда (как Sqrt в asm, я был бы рад некоторым рекомендациям.

1 2

1 ответ:

Сначала нужно линеаризовать адрес:

  &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