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
; Выделяем общий буфер под все три матрицы подряд
; A занимаем первые 10000 элементов, B — следующие 10000, C — последние 10000
arr: resd 30015
section .text
global main
extern scanf, printf
main:
push ebp
mov ebp, esp
push esi
push edi
; 1. Читаем N, M, K
push K
push M
push N
push fmt_3
call scanf
add esp, 16
; 2. Считываем матрицы A и B подряд в один цикл
mov eax, [N]
imul eax, [M] ; EAX = N * M
mov ecx, [M]
imul ecx, [K] ; ECX = M * K
add ecx, eax ; ECX = общая длина (N*M + M*K)
xor esi, esi
.read_loop:
cmp esi, ecx
jge .mult_prep
lea eax, [arr + esi*4]
push ecx ; сохраняем счетчик
push eax
push fmt_i
call scanf
add esp, 8
pop ecx ; восстанавливаем счетчик
inc esi
jmp .read_loop
; 3. Умножение матриц C = A * B
; Смещения матриц: A = arr, B = arr + N*M*4, C = arr + (N*M + M*K)*4
.mult_prep:
xor esi, esi ; esi = i = 0
.loop_i:
cmp esi, [N]
jge .print_prep
xor edi, edi ; edi = j = 0
.loop_j:
cmp edi, [K]
jge .next_i
xor ecx, ecx ; ecx = sum = 0
xor edx, edx ; edx = l = 0
.loop_l:
cmp edx, [M]
jge .store_C
; Матрица A (строка i, столбец l): индекс = i * M + l
mov eax, esi
imul eax, [M]
add eax, edx
mov ebx, [arr + eax*4]
; Матрица B (строка l, столбец j): индекс = N*M + l * K + j
mov eax, [N]
imul eax, [M] ; смещение начала B
push edx
imul edx, [K]
add eax, edx
add eax, edi
pop edx
mov eax, [arr + eax*4]
imul eax, ebx
add ecx, eax ; sum += A[i][l] * B[l][j]
inc edx ; l++
jmp .loop_l
.store_C:
; Матрица C (строка i, столбец j): индекс = N*M + M*K + i * K + j
mov eax, [N]
imul eax, [M]
mov ebx, [M]
imul ebx, [K]
add eax, ebx ; смещение начала C
push ecx
mov ecx, esi
imul ecx, [K]
add eax, ecx
add eax, edi
pop ecx
mov [arr + eax*4], ecx ; сохраняем в C
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, [N]
imul eax, [M]
mov ebx, [M]
imul ebx, [K]
add eax, ebx
mov ebx, esi
imul ebx, [K]
add eax, ebx
add eax, edi
push dword [arr + eax*4]
push fmt_i
call printf
add esp, 4 ; частично чистим стек, оставляя место под fmt_sp
mov dword [esp], 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
mov esp, ebp
pop ebp
xor eax, eax
ret