Я пишу код для умножения матриц на языке ассемблера. Я не могу использовать переменные и только хранилище в стеке, что мне нужно. Алгоритм кажется правильным, но у меня проблемы с IMUL и MOV с использованием регистров в последних двух блоках кода. Я отправляю мой код здесь:Матричное умножение в сборке
unsigned int m = 3; // raws of mat1
unsigned int n = 2; // columns of mat1
unsigned int k = 4; // columns of mat2
short int mat1[] = { -1,-2, 4,5, 4,-2 }; // first matrix
short int mat2[] = { 2,0,4,6, 0,2,-1,3 }; // second matrix
int mat3[1024]; // output matrix
__asm {
XOR EAX, EAX //mat1 raws counter
XOR EBX, EBX //mat2 columns counter
XOR EDX, EDX //mat1 columns(equal to mat2 raws) counter
XOR EDI, EDI //will contain sum of multiplications to be copied into output matrix
Loop1 : //determinates the raws of output matrix: mat3
XOR EBX, EBX //at the end of first raw, column counter is resetted
CMP m, EAX //if loopped mat1 m-raws times...
JZ Finale //...algortihm is over
INC EAX //increase mat1 raws counter
JMP Loop2
Loop2 : //determinates the columns of mat3
XOR EDX, EDX //at the end of the n-sums, mat1 column counter is resetted
XOR EDI, EDI //after sum of n-multiplications edi is resetted
CMP k, EBX //if multiplications/sums on this raw have been done...
JZ Loop1 //...go to next output matrix raw
INC EBX //increase mat2 columns counter
JMP Loop3
Loop3 : //determinates elements of mat3
CMP n, EDX //if the n-multiplacations/sums on first n-elements have been done...
JZ Loop2 //...skip to next n-elements
INC EDX //increase counter of the elements that will be multiplicate
JMP Stuffs //go to operations code block
Stuffs : //here code generates mat3 elements
#58 MOV SI, mat1[2 * ((EAX - 1) * 2 + (EDX - 1)] //moves to SI the [m-raws/n-clomumn] element of mat1
#59 IMUL SI, mat2[2 * ((EBX - 1) * 2 + (EDX - 1)] //multiplicates(with sign) SI and [n-raws/k-column] element of mat2
ADD DI, SI //sum the result in edi
CMP n, EDX //check the sums
JZ CopyResult //if n-sums have been done...
JMP Loop3 //...go to copy result into mat3
CopyResult :
#66 MOV mat3[4 * ((EAX - 1) * 4 + (EBX - 1))], EDI //copy value to output matrix mat3
JMP Loop3 //go to next n-elements
Finale :
}
{
unsigned int i, j, h;
printf("Output matrix:\n");
for (i = h = 0; i < m; i++) {
for (j = 0; j < k; j++, h++)
printf("%6d ", mat3[h]);
printf("\n");
}
}
В этом коде, компилятор сообщает о двух типах ошибок, относящихся IMUL и MOV для MAT1, MAT2 и mat3. Вот они:
- Линия 58 - Ошибка C2404 'EDX': запрещенный регистр в 'втором операнде'
- Line 58 - Ошибка C2430 более чем один индексный регистр в 'втором операнде'
Те же ошибки для строк 59 и 66, с регистрами EDX и EBX.
Является ли это algortihm в основном хорошим? (я проверил установку вручную некоторых индексов , а затем последний, во время отладки, и это было хорошо, но я не смог полностью его протестировать).
Я думаю, что первая ошибка зависит от второй, но если i не может использовать этот способ регистров, что я могу сделать для вычисления вывода?
'[2 * ((EAX - 1) * 2 + (EDX - 1)]', '[2 * ((EBX - 1) * 2 + (EDX - 1)]" и '[4 * ((EAX - 1) * 4 + (EBX - 1))] 'недействительный режим адресации: https://courses.engr.illinois.edu/ece390/books/artofasm/CH04/CH04-3.html –
Ваш последняя версия вопроса имела C-декларации для ввода и вывода, поэтому мы могли видеть, что вы имеете дело с «коротким». Реальным вопросом здесь является только адресация режимов и синтаксических ошибок. Вы не указали, какая строка дает ошибку. –
@Peter Cordes - Хорошо, я редактировал вопрос. Возможно, что если петли теперь работают правильно, самая большая проблема заключается в том, как обращаться с регистрами на блок вычисления. – Caramelleamare