section .data
fmt_3: db "%d %d %d", 0
fmt_i: db "%d", 0
fmt_sp: db " ", 0
fmt_nl: db 10, 0
section .bss
N: resd 1
M: resd 1
K: resd 1
limit: resd 1 ; Лимит для цикла чтения (N*M + M*K)
ptr_B: resd 1 ; Базовый адрес начала матрицы B в байтах
ptr_C: resd 1 ; Базовый адрес начала матрицы C в байтах
arr: resd 30015 ; Единый массив для A, B и C
section .text
global main
extern scanf, printf
main:
push ebp
mov ebp, esp
push ebx
push esi
push edi
; 1. Читаем N, M, K
push K
push M
push N
push fmt_3
call scanf
add esp, 16
; Вычисляем смещения матриц и лимит чтения
mov eax, [N]
imul eax, [M] ; EAX = N * M (размер A)
lea ebx, [arr + eax*4]
mov [ptr_B], ebx ; ptr_B = адрес начала B
mov ecx, [M]
imul ecx, [K] ; ECX = M * K (размер B)
lea edx, [ebx + ecx*4]
mov [ptr_C], edx ; ptr_C = адрес начала C
add ecx, eax
mov [limit], ecx ; limit = N*M + M*K
; 2. Считываем матрицы A и B в одном цикле
xor esi, esi ; esi = текущий индекс элемента
.read_loop:
cmp esi, [limit] ; Безопасно проверяем лимит из памяти
jge .mult_prep
lea eax, [arr + esi*4]
push eax
push fmt_i
call scanf
add esp, 8
inc esi
jmp .read_loop
; 3. Умножение матриц C = A * B
; Роли регистров: ESI = i, EDI = j, EBX = l
.mult_prep:
xor esi, esi ; i = 0
.loop_i:
cmp esi, [N]
jge .print_prep
xor edi, edi ; j = 0
.loop_j:
cmp edi, [K]
jge .next_i
xor ecx, ecx ; ECX = sum = 0 (аккумулятор)
xor ebx, ebx ; l = 0
.loop_l:
cmp ebx, [M]
jge .store_C
; Матрица A[i][l] -> индекс = i * M + l
mov eax, esi
imul eax, [M]
add eax, ebx
mov edx, [arr + eax*4] ; edx = A[i][l]
; Матрица B[l][j] -> индекс = l * K + j
mov eax, ebx
imul eax, [K]
add eax, edi ; теперь eax = l * K + j
; Берем базу ptr_B из памяти, не трогая EDI
push ecx ; временно сохраняем промежуточную сумму
mov ecx, [ptr_B]
mov eax, [ecx + eax*4] ; eax = B[l][j]
imul eax, edx ; eax = A[i][l] * B[l][j]
pop ecx ; восстанавливаем сумму
add ecx, eax ; sum += eax
inc ebx ; l++
jmp .loop_l
.store_C:
; Матрица C[i][j] -> индекс = i * K + j
mov eax, esi
imul eax, [K]
add eax, edi
mov edx, [ptr_C]
mov [edx + eax*4], ecx ; Сохраняем итоговую sum в C[i][j]
inc edi ; j++
jmp .loop_j
.next_i:
inc esi ; i++
jmp .loop_i
; 4. Вывод матрицы C
.print_prep:
xor esi, esi ; i = 0
.print_i:
cmp esi, [N]
jge .exit
xor edi, edi ; j = 0
.print_j:
cmp edi, [K]
jge .print_nl
; Индекс элемента C[i][j]
mov eax, esi
imul eax, [K]
add eax, edi
mov edx, [ptr_C]
push dword [edx + eax*4]
push fmt_i
call printf
add esp, 8
push fmt_sp
call printf
add esp, 4
inc edi
jmp .print_j
.print_nl:
push fmt_nl
call printf
add esp, 4
inc esi
jmp .print_i
.exit:
pop edi
pop esi
pop ebx
mov esp, ebp
pop ebp
xor eax, eax
ret