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
; Базовые указатели на начала матриц B и C в плоском массиве
ptr_B: resd 1
ptr_C: resd 1
; Общий буфер для всех матриц (10000 * 3)
arr: resd 30015
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
; Считаем размеры и базовые адреса для B и C
mov eax, [N]
imul eax, [M] ; EAX = N * M (размер A)
lea ebx, [arr + eax*4]
mov [ptr_B], ebx ; ptr_B = arr + N * M * 4
mov ecx, [M]
imul ecx, [K] ; ECX = M * K (размер B)
lea edx, [ebx + ecx*4]
mov [ptr_C], edx ; ptr_C = ptr_B + M * K * 4
add ecx, eax ; ECX = общая длина чтения (N*M + M*K)
; 2. Считываем матрицы A и B в один цикл
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
.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] -> берём значение из ptr_B + (l * K + j) * 4
mov eax, edx
imul eax, [K]
add eax, edi
mov edi, [ptr_B] ; временно используем edi под базу
mov eax, [edi + eax*4] ; теперь eax честно хранит значение B[l][j]
mov edi, [esp] ; восстанавливаем j из стека (он там лежит как копия сохраненного edi)
imul eax, ebx
add ecx, eax ; sum += A[i][l] * B[l][j]
inc edx ; l++
jmp .loop_l
.store_C:
; Матрица C[i][j] -> ptr_C + (i * K + j) * 4
mov eax, esi
imul eax, [K]
add eax, edi
mov ebx, [ptr_C]
mov [ebx + eax*4], ecx ; Сохраняем sum
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 ebx, [ptr_C]
; Исправлено: Честный и безопасный вывод через стек cdecl
push dword [ebx + 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