Online Compiler Nasm

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
This code reads three dimensions N, M, K, then reads two matrices A (size N×M) and B (size M×K) into a single flat array, multiplies them to produce matrix C (size N×K), and prints C. The matrices are stored sequentially in the flat array `arr`: first A, then B, then C.

- In the multiplication loop, the code uses register `edi` for the column index j, but then overwrites it with `[ptr_B]` when accessing B[l][j]. Later it tries to restore j from the stack, but there is no saved copy of j on the stack at that point. This corrupts the j loop counter.
- The reading loop saves and restores `ecx` around `scanf`, but `ecx` is used as the loop limit. After `scanf` returns, `ecx` is restored, but `scanf` may modify other registers (like `eax`, `ecx`, `edx`) according to cdecl calling convention. The code does not preserve all necessary registers.