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
Проблема заключается в том, как сложить последний элемент матриц, если количество элементов не четное?