GAS/AT&T Сложение матриц

Задача: Переписать код с "С" в "Ассемблер АТ&T"

    double* sum(double* matrixA, int N1, int M1, double* matrixB, int N2, int M2)
{
    if ((N1 == N2) && (M1 == M2)) {
        double* matrixC = (double*)malloc(N1 * M2 * sizeof(double));
        for (int i = 0; i < N1*M1; i++) {
            matrixC[i] = (matrixA[i] + matrixB[i]);
        }
        return matrixC;
    }
    else printf("Sum: Matrix not equels\n");
    return 0;
}

Написал следующее:

.globl sumAs
 
.data
    format: .string "%s\n"  
    mess: .string "Sum: Matrix not equals\n"
    
/* Для передачи параметров в 64-х битовых операционных системах Linux 
последовательно используют шесть регистров: 
rdi, matrixA 
rsi, N1
rdx, M1
rcx, matrixB
r8,  N2
r9.  M2
*/
 
.text
 
.func
sumAs:
    sub $8, %rsp // %rsp = 16x
    
permission_check:
    push %rsi // -8 
    push %rdx // -16 запомнили стороны матрицы
    
    cmp %rsi, %r8
    JNE print_end_message
    cmp %rdx, %r9
    JNE print_end_message
    
    pop %rdx // -8 
    pop %rsi // 16x стек пуст значения извлечены
    
init_memory:
    push %rdi // -8  освободили регистр %rdi для malloc 
    push %rcx // -16 сохранили matrixB
    imul %rsi, %rdx // результат умножения в %rdx
    push %rdx // -24 сохранили результат умножения 
    sub $8, %rsp // -32 стек кратен 16
    
    mov %rdx, %rdi
    lea (, %rdi, 8), %rdi // умножили %rdi на 8
    call malloc // кушает %rdi возвращает %rax
    
    add $8, %rsp // -24
    pop %rdx // -16
    pop %rcx // -8 
    pop %rdi // 16x 
 
    xor %rsi, %rsi // создали счетчик равный 0
    and $-2, %rdx // Это выравнивание на четное количество элементов массива?
    
/*
rax, matrixC ссылка на выделенную память malloc
rdi, matrixA 
rsi, 0
rdx, size (N1*M1)
rcx, matrixB
r8,  ???
r9.  ???
*/
 
a_start_sum:
    cmp %rdx, %rsi  // (i - size)
    jge end_loop  // if (i - size) ≥ 0 goto end_loop
    
    movapd (%rdi, %rsi, 8), %xmm0         
    addpd  (%rcx, %rsi, 8), %xmm0         
    movapd %xmm0, (%rax, %rsi, 8)     
    
    add $2, %rsi    
    jmp a_start_sum
    
    // здесь нужно сложить оставшийся кусочек если он есть
 
end_loop:
    add $8, %rsp
    ret // выход с выводом matrixC //
    
print_end_message:
    add $16, %rsp // очистка
    
    lea format(%rip), %rdi // сюда передаем первый аргумент для принта. Строковый тип данных
    lea mess(%rip), %rsi // ссылка на место хранения строки 
    mov $0, %al
    call printf
    
    xor %eax, %eax
    add $8, %rsp
    ret
    
.endfunc

Проблема заключается в том, как сложить последний элемент матриц, если количество элементов не четное?


Ответы (0 шт):