Задать вопрос
KoshakSB
@KoshakSB
студент ггту сухого

Почему не работает подсчёт произведения элементов массива masm32(ассемблер)?

.686
.model flat, stdcall ; определяем модель памяти и
; модель вызова функций
option casemap:none ; отключаем регистрозависимость
; Библиотеки и подключаемые файлы проекта
;--------------------------------------------
include C:\masm32\include\windows.inc
include C:\masm32\include\user32.inc
include C:\masm32\include\kernel32.inc
include C:\masm32\include\masm32.inc
includelib C:\masm32\lib\user32.lib
includelib C:\masm32\lib\kernel32.lib
includelib C:\masm32\lib\masm32.lib
; Сегмент данных
;--------------------------------------------
.data
sConsTitle BYTE "Laba №4", 0
Arr DWORD 2, 2, 2, 3 ; двумерный массив 4x4
RowSize = ($ - Arr)
DWORD 2, 2, 2, 2
DWORD 1, 2, 2, 2
DWORD 2, 2, 2, 2
typeArr BYTE TYPE Arr ; размер элемента в байтах
row BYTE 4 ; число строк
col BYTE 4 ; число столбцов
i BYTE 0 ; индекс строки
j BYTE 0 ; индекс столбца
sum DWORD 0 ; переменная для хранения суммы
resultText BYTE "Answer: "
resultStr BYTE 20 DUP(?), 0
buffer BYTE 20 DUP(?), 0
tab BYTE ' ', 0
clrt BYTE 0Ah, 0Dh, 0
; Сегмент кода
;--------------------------------------------
.code
start:
; вывод заголовка консоли
invoke SetConsoleTitle, ADDR sConsTitle
; вывод массива
xor ecx, ecx ; ECX = 0
mov cl, row ; ECX = row - загружаем счётчик строк
mov esi, 0 ; ESI = 0 - указатель на нулевую строку
loop_row_1:
push ecx ; сохраняем счётчик внешнего цикла в стек
xor ecx, ecx ; ECX = 0
mov cl, col ; ECX = col - загружаем счётчик столбцов
mov ebx, 0 ; EBX = 0 - указатель на нулевой столбец
loop_col_1:
mov eax, Arr[esi][ebx] ; EAX <- Arr[i][j]
push ebx ; сохраняем регистры перед
; использованием ltoa и StdOut
push ecx
push esi
invoke ltoa, eax, ADDR buffer ; преобразование Arr[i][j] в строку
invoke StdOut, ADDR buffer ; вывод Arr[i][j]
invoke StdOut, ADDR tab ; вывод TAB
pop esi ; восстанавливаем регистры из стека
pop ecx
pop ebx
add ebx, TYPE Arr ; увеличиваем указатель столбцов на
; размер одного элемента
loop loop_col_1 ; проверяем окончание строки
invoke StdOut, ADDR clrt ; переходим на следующую строку
add esi, RowSize ; увеличиваем указатель строки на
; размер одной строки
pop ecx ; восстанавливаем счётчик внешнего цикла
loop loop_row_1 ; проверяем окончание массива
;--------------------------------------------
; вычисление произведения элементов, делящихся на 2
xor ecx, ecx ; ECX = 0
mov cl, row ; ECX = row - загружаем счётчик строк
mov esi, 0 ; ESI = 0 - указатель на нулевую строку
mov i, 0
mov sum, 1 ; начальное значение произведения
loop_row_2:
    push ecx ; сохраняем счётчик внешнего цикла в стек
    xor ecx, ecx ; ECX = 0
    mov cl, col ; ECX = col - загружаем счётчик столбцов
    mov ebx, 0 ; EBX = 0 - указатель на нулевой столбец
    mov j, 0
loop_col_2:
    mov eax, Arr[esi][ebx] ; EAX <- Arr[i][j]
    test eax, 1 ; проверяем делится ли текущий элемент на 2
    jnz not_divisible ; если не делится, переходим к следующему элементу
   ; сохраняем значения EDX и EAX перед умножением
push edx
push eax

; умножаем текущий элемент на произведение
mul sum

; восстанавливаем значения EDX и EAX
pop eax
pop edx

; добавляем результат в произведение
add sum, eax
adc sum, edx  ; если произошло переполнение, учитываем перенос из EDX

not_divisible:
    inc j ; увеличиваем индекс столбца
    add ebx, TYPE Arr ; увеличиваем указатель столбцов на
    ; размер одного элемента
    loop loop_col_2 ; проверяем окончание строки
    add esi, RowSize ; увеличиваем указатель строки на
    ; размер одной строки
    pop ecx ; восстанавливаем счётчик внешнего цикла
    loop loop_row_2 ; проверяем окончание массива

;--------------------------------------------
; вывод результата
invoke ltoa, sum, ADDR resultStr ; преобразование SUM в строку
invoke StdOut, ADDR resultText ; вывод результата
invoke Sleep, INFINITE
; завершение процессов Windows
invoke ExitProcess, NULL
; окончание сегмента start
end start

6621370ed14c3055424193.jpeg
  • Вопрос задан
  • 76 просмотров
Подписаться 1 Простой 1 комментарий
Решения вопроса 1
KoshakSB
@KoshakSB Автор вопроса
студент ггту сухого
.686
.model flat, stdcall ; определяем модель памяти и
; модель вызова функций
option casemap:none ; отключаем регистрозависимость
; Библиотеки и подключаемые файлы проекта
;--------------------------------------------
include C:\masm32\include\windows.inc
include C:\masm32\include\user32.inc
include C:\masm32\include\kernel32.inc
include C:\masm32\include\masm32.inc
includelib C:\masm32\lib\user32.lib
includelib C:\masm32\lib\kernel32.lib
includelib C:\masm32\lib\masm32.lib
; Сегмент данных
;--------------------------------------------
.data
sConsTitle BYTE "Laba №4", 0
Arr DWORD 2, 2, 2, 3 ; двумерный массив 4x4
RowSize = ($ - Arr)
DWORD 2, 2, 2, 2
DWORD 1, 2, 2, 2
DWORD 2, 2, 2, 2
typeArr BYTE TYPE Arr ; размер элемента в байтах
row BYTE 4 ; число строк
col BYTE 4 ; число столбцов
i BYTE 0 ; индекс строки
j BYTE 0 ; индекс столбца
sum DWORD 0 ; переменная для хранения суммы
resultText BYTE "Answer: "
resultStr BYTE 20 DUP(?), 0
buffer BYTE 20 DUP(?), 0
tab BYTE ' ', 0
clrt BYTE 0Ah, 0Dh, 0
; Сегмент кода
;--------------------------------------------
.code
start:
; вывод заголовка консоли
invoke SetConsoleTitle, ADDR sConsTitle
; вывод массива
xor ecx, ecx ; ECX = 0
mov cl, row ; ECX = row - загружаем счётчик строк
mov esi, 0 ; ESI = 0 - указатель на нулевую строку
loop_row_1:
push ecx ; сохраняем счётчик внешнего цикла в стек
xor ecx, ecx ; ECX = 0
mov cl, col ; ECX = col - загружаем счётчик столбцов
mov ebx, 0 ; EBX = 0 - указатель на нулевой столбец
loop_col_1:
mov eax, Arr[esi][ebx] ; EAX <- Arr[i][j]
push ebx ; сохраняем регистры перед
; использованием ltoa и StdOut
push ecx
push esi
invoke ltoa, eax, ADDR buffer ; преобразование Arr[i][j] в строку
invoke StdOut, ADDR buffer ; вывод Arr[i][j]
invoke StdOut, ADDR tab ; вывод TAB
pop esi ; восстанавливаем регистры из стека
pop ecx
pop ebx
add ebx, TYPE Arr ; увеличиваем указатель столбцов на
; размер одного элемента
loop loop_col_1 ; проверяем окончание строки
invoke StdOut, ADDR clrt ; переходим на следующую строку
add esi, RowSize ; увеличиваем указатель строки на
; размер одной строки
pop ecx ; восстанавливаем счётчик внешнего цикла
loop loop_row_1 ; проверяем окончание массива
;--------------------------------------------
; вычисление произведения элементов, делящихся на 2
xor ecx, ecx ; ECX = 0
mov cl, row ; ECX = row - загружаем счётчик строк
mov esi, 0 ; ESI = 0 - указатель на нулевую строку
mov i, 0
mov sum, 1 ; начальное значение произведения
loop_row_2:
    push ecx ; сохраняем счётчик внешнего цикла в стек
    xor ecx, ecx ; ECX = 0
    mov cl, col ; ECX = col - загружаем счётчик столбцов
    mov ebx, 0 ; EBX = 0 - указатель на нулевой столбец
    mov j, 0
loop_col_2:
    mov eax, Arr[esi][ebx] ; EAX <- Arr[i][j]
    test eax, 1 ; проверяем делится ли текущий элемент на 2
    jnz not_divisible ; если не делится, переходим к следующему элементу

    ; умножаем текущий элемент на произведение
    imul sum, eax

not_divisible:
    inc j ; увеличиваем индекс столбца
    add ebx, TYPE Arr ; увеличиваем указатель столбцов на размер одного элемента
    loop loop_col_2 ; проверяем окончание строки

;--------------------------------------------
; вывод результата
invoke ltoa, sum, ADDR resultStr ; преобразование SUM в строку
invoke StdOut, ADDR resultText ; вывод результата
invoke Sleep, INFINITE
; завершение процессов Windows
invoke ExitProcess, NULL
; окончание сегмента start
end start

Есть ещё такой вариант, но он просто не ассемблируется
662137bce1c87599836740.png

//Ниже рабочий код и скрин работы
.686
.model flat, stdcall ; определяем модель памяти и
; модель вызова функций
option casemap:none ; отключаем регистрозависимость
; Библиотеки и подключаемые файлы проекта
;--------------------------------------------
include C:\masm32\include\windows.inc
include C:\masm32\include\user32.inc
include C:\masm32\include\kernel32.inc
include C:\masm32\include\masm32.inc
includelib C:\masm32\lib\user32.lib
includelib C:\masm32\lib\kernel32.lib
includelib C:\masm32\lib\masm32.lib
; Сегмент данных
;--------------------------------------------
.data
sConsTitle BYTE "Laba №4", 0
Arr DWORD 2, 2, 2, 3 ; двумерный массив 4x4
RowSize = ($ - Arr)
DWORD 2, 2, 2, 2
DWORD 1, 2, 2, 2
DWORD 2, 2, 2, 2
typeArr BYTE TYPE Arr ; размер элемента в байтах
row BYTE 4 ; число строк
col BYTE 4 ; число столбцов
i BYTE 0 ; индекс строки
j BYTE 0 ; индекс столбца
sum DWORD 1 ; переменная для хранения произведения
resultText BYTE "Answer: "
resultStr BYTE 20 DUP(?), 0
buffer BYTE 20 DUP(?), 0
tab BYTE ' ', 0
clrt BYTE 0Ah, 0Dh, 0
; Сегмент кода
;--------------------------------------------
.code
start:
; вывод заголовка консоли
invoke SetConsoleTitle, ADDR sConsTitle
; вывод массива
xor ecx, ecx ; ECX = 0
mov cl, row ; ECX = row - загружаем счётчик строк
mov esi, 0 ; ESI = 0 - указатель на нулевую строку
loop_row_1:
push ecx ; сохраняем счётчик внешнего цикла в стек
xor ecx, ecx ; ECX = 0
mov cl, col ; ECX = col - загружаем счётчик столбцов
mov ebx, 0 ; EBX = 0 - указатель на нулевой столбец
loop_col_1:
mov eax, Arr[esi][ebx] ; EAX <- Arr[i][j]
push ebx ; сохраняем регистры перед
; использованием ltoa и StdOut
push ecx
push esi
invoke ltoa, eax, ADDR buffer ; преобразование Arr[i][j] в строку
invoke StdOut, ADDR buffer ; вывод Arr[i][j]
invoke StdOut, ADDR tab ; вывод TAB
pop esi ; восстанавливаем регистры из стека
pop ecx
pop ebx
add ebx, TYPE Arr ; увеличиваем указатель столбцов на
; размер одного элемента
loop loop_col_1 ; проверяем окончание строки
invoke StdOut, ADDR clrt ; переходим на следующую строку
add esi, RowSize ; увеличиваем указатель строки на
; размер одной строки
pop ecx ; восстанавливаем счётчик внешнего цикла
loop loop_row_1 ; проверяем окончание массива
;--------------------------------------------
; вычисление произведения элементов, делящихся на 2
xor ecx, ecx ; обнуляем счетчик строк
mov cl, row ; загружаем количество строк
mov esi, 0 ; указываем на нулевую строку
mov i, 0

loop_row_2:
    push ecx ; сохраняем счетчик внешнего цикла в стек
    xor ecx, ecx ; обнуляем счетчик столбцов
    mov cl, col ; загружаем количество столбцов
    mov ebx, 0 ; указываем на нулевой столбец
    mov j, 0

loop_col_2:
    mov eax, Arr[esi][ebx] ; загружаем элемент массива в eax
    test eax, 1 ; проверяем делится ли текущий элемент на 2
    jnz not_divisible ; если не делится, переходим к следующему элементу

    ; умножаем текущий элемент на произведение
 mov edx, sum     ; сохраняем текущее произведение в edx
    imul eax, edx    ; умножаем текущий элемент на произведение
    mov sum, eax     ; сохраняем результат в sum
not_divisible:
    inc j ; увеличиваем индекс столбца
    add ebx, TYPE Arr ; увеличиваем указатель столбцов на размер одного элемента
    loop loop_col_2 ; проверяем окончание строки

    add esi, RowSize ; увеличиваем указатель строки на размер строки
    pop ecx ; восстанавливаем счетчик внешнего цикла
    loop loop_row_2 ; проверяем окончание массива

;--------------------------------------------
; вывод результата
invoke ltoa, sum, ADDR resultStr ; преобразование SUM в строку
invoke StdOut, ADDR resultText ; вывод результата
invoke Sleep, INFINITE
; завершение процессов Windows
invoke ExitProcess, NULL
; окончание сегмента start
end start

6621407a221ec596045555.jpeg
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы