Консультация № 191366
19.09.2017, 11:37
0.00 руб.
0 11 1
Здравствуйте, уважаемые эксперты! Прошу вас ответить на следующий вопрос:

Имеется задача. Даны 3 квадратные матрицы различных размерностей. Для каждой из них заменить нулями все ее четные элементы, расположенные на главной диагонали или выше нее. Подсчитать количество таких замен.
Имеется код TASM(очень корявый, возможно неработающий), но программа нужна на NASM


Приложение:
code segment para public 'code'; заголовок сегмента
assume cs:code,ds:code,es:code,ss:code
;сообщим транслятору о намерении установить сегментные
; регистры cs, ds, es на наш сегмент
org 100h ; место под PSP beg:
prd: jmp start ; переход на start
messel db 0ah,0dh,'Введите элемент массива : $' ; приглашение для
; ввода размерности.
;Коды 0ah и 0dh означают переход
;на начало следующей строки

messmas db 0ah,0dh,'Введите элементы $' ;приглашение для
; ввода элементов матрицы
messmas2 db '-го массива:$
mess3 db 0ah,0dh,'Массив: $' ;заголовок для вывода элементов массива

answer_buf db 7 dup(?), ' ','$' ; буфер под ответ (вывод)
input_buf db 06,00,5 dup(?) ;Память под буфер ввода
bufer db 0ah,0,11 dup(?) ; буфер для ввода
; размерность матрицы
mas1 dw 25 dup(?) ; память под матрицу
mas2 dw 25 dup(?) ; память под матрицу
mas3 dw 25 dup(?) ; память под матрицу

newline db 0ah,0dh,'$' ; для перевода строки
include bin2str.asm
; подключение процедуры bin2str, находящейся в файле
; bin2str.asm и осуществляющей преобразование числа в строку
; вход bin2str - ax - число;
; выход - строка по адресу ds:bx
include str2bin.asm
; подключение процедуры str2bin, находящейся в файле
; str2bin.asm и осуществляющей преобразование из строки в число
; вход str2bin - ds:bx - адрес строки
; выход - ax - число со знаком

; input – подпрограмма для ввода одного числа
; Вход: в dx - адрес буфера,
; Выход: в ax возвращается введенное число

; Макроопределение для вывода строки на экран.
OutPutMess MACRO message
lea dx,message ; Адрес строки -> в dx
mov ah,09h ; Номер функции вывода
int 21h
ENDM
input proc
push bx ;сохраним используемые регистры
push dx
push dx ;сохраним адрес буфера, т.к. он
; будет запорчен при организации вывода строки newline
lea dx,newline
mov ah,09h
int 21h ;вывод строки
pop dx ; восстановим адрес буфера ввода
mov ah,0ah ;помещаем в ah номер прерывания
int 21h ;для ввода строки
mov bx,dx ;строка по адресу ds:dx
inc bx ;увеличиваем на 1 ee адрес
; и передаем его в процедуру str2bin
call str2bin ;преобразуем строку в число
pop dx ;число будет в ax
pop bx
ret
input endp
; Макроопределение для организации ввода элементов массива
; с клавиатуры. Параметры – имя массива и количество элементов
Input_mas MACRO mas,amnt
LOCAL v1, v2
lea bx,mas ; в bx запишем адрес начала матрицы A
push bx
mov si,0 ; смещение от начала матрицы равно нулю
mov cx,amnt ; в cx запишем счетчик цикла по строкам
v1: push cx ; перед организацией цикла сохраним его
mov cx,amnt ; в cx запишем счетчик цикла по столбцам
v2: push cx ; сохраним счетчик внутреннего цикла
lea dx,messel
mov ah,09h
int 21h ; вывод строки
lea dx,input_buf ; Организация непосредственного ввода элементов
mov ah,0ah ; помещаем в ah номер прерывания
int 21h ; для ввода строки
mov bx,dx ; строка по адресу ds:dx
inc bx ; увеличиваем на 1 ee адрес
; и передаем его в процедуру str2bin
call str2bin ; преобразуем строку в число
pop bx
mov [bx][si],ax ; и запишем его в матрицу A по
; адресу (bx)+(si) с помощью базово-индексной адресации
add si,2 ; переход к следующему элементу
pop cx ; восстановим счетчик цикла
loop v2 ; продолжим цикл ввода элементов одной строки
pop cx ; восстановим счетчик внешнего цикла
loop v1 ; перейдем к следующей строке
ENDM

; Макроопределение для проверки массива на наличие
; 2-х идущих подряд нулевых элементов. Параметры – имя
; массива и количество элементов.
MasView MACRO mas,amnt
LOCAL cycl,m1,m2,m3
lea bx, mas ; запоминаем адрес массива
mov si, 0 ; индекс колонки в строке
mov cl, amnt ; число строк
lRow: mov cl, amnt ; цикл по строкам, число колонок в строке
lCol: cmp cl, ch ; элементы на главной диагонали и ниже
jg next ; пропускаем
mov ax, mas[bx][si] ; берем элемент bx строки si столбца
test ax, 1 ; четное число?
jz Changed ; четное, переход на метку Changed
inc si ; на следующий элемент в строке
dec cl ; уменьшаем счетчик колонок
jnz lCol ; на следующую колонку строки
add si, amnt ; строка закончилась, смещаем базу строки на длину строки
dec ch ; уменьшаем счетчик строк
jnz lRow ; на следующую строку
Changed:mov ax,0
next: inc si ; на следующий элемент в строке
dec cl ; уменьшаем счетчик колонок
jnz lCol ; на следующую колонку строки
add si, amnt ; строка закончилась, смещаем базу строки на длину строки
dec ch ; уменьшаем счетчик строк
jnz lRow ; на следующую строку
ENDM


; Основная программа
start:
IRPC num,<123>
OutPutMess messmas
mov ax,&num
lea bx,messNUM
call bin2str
Input_mas mas&num,5
masview mas&num,5
ENDM
int 20h ;завершение работы программы
code ends ;конец сегмента кода
end prg

Обсуждение

давно
Посетитель
399275
16
19.09.2017, 11:55
общий
19.09.2017, 12:30
Размер переменных двойное слово, в программе необходимы макросы
давно
Старший Модератор
31795
6196
19.09.2017, 16:16
общий
это ответ
Здравствуйте, ksenya241!

Писал в FASM, компилировал NASM:
[code lang=asm h=250]org 100h
mov cx,3
mov di,ddArray
mov si,dwSize
@@01: call inputMatrix
add si,2
loop @@01
mov cx,3
mov di,ddArray
mov si,dwSize
@@02: call jobMatrix
add si,2
loop @@02
mov cx,3
mov di,ddArray
mov si,dwSize
@@03: call outputMatrix
add si,2
loop @@03
xor ax,ax
int 16h
ret
inputMatrix:
inc byte[dbMatrixSize]
inc byte[dbMatrixNumber]
push cx
IM0: mov ah,9
mov dx,dbEnterSize
int 21h
call inputNumber
or ax,ax
jz IM0
mov [si],ax
mov cx,[si]
IM1: push cx
call convertNumber
mov [dwRowIn],ax
mov cx,[si]
IM2: call convertNumber
mov [dwColIn],ax
mov ah,9
mov dx,dbEnterNumber
int 21h
call inputNumber
stosd
loop IM2
pop cx
loop IM1
pop cx
ret
jobMatrix:
push cx
mov cx,[si]
JM1: mov bx,cx
mov cx,[si]
JM2: cmp bx,cx
jb JM3
mov eax,[di]
test eax,1
jnz JM3
xor eax,eax
mov [di],eax
JM3: add di,4
loop JM2
mov cx,bx
loop JM1
pop cx
ret
outputMatrix:
push cx
inc byte[dbMatrixName]
xor cx,cx
call convertNumber
mov [dwRowOut],ax
mov [dwColOut],ax
mov ah,9
mov dx,dbOutputMatrix
int 21h
mov cx,[si]
OM1: push cx
mov al,10
int 29h
mov al,13
int 29h
mov cx,[si]
OM2: mov eax,[di]
call outputNumber
add di,4
loop OM2
pop cx
loop OM1
pop cx
ret
inputNumber:
push di
xor edi,edi
mov ebx,10
IN1: xor ax,ax
int 16h
cmp al,13
jz IN2
cmp al,'0'
jb IN1
cmp al,'9'
ja IN2
int 29h
and eax,0Fh
xchg edi,eax
xor edx,edx
mul ebx
add edi,eax
jmp IN1
IN2: mov eax,edi
pop di
ret
outputNumber:
push cx
mov ebx,10
xor cx,cx
ON1: xor edx,edx
div ebx
push dx
inc cx
or eax,eax
jnz ON1
mov al,' '-30h
ON2: push ax
inc cx
cmp cx,6
jb ON2
ON3: pop ax
add al,30h
int 29h
loop ON3
pop cx
ret
convertNumber:
mov ax,[si]
sub ax,cx
aam
add ax,3031h
xchg al,ah
ret
dbEnterSize db 10,13,'Enter matrix '
dbMatrixSize db '@ size:$'
dbOutputMatrix db 10,10,13,'Output matrix '
dbMatrixName db '@['
dwRowOut dw 0
db ','
dwColOut dw 0
db ']:$'
dbEnterNumber db 10,13,'Enter value '
dbMatrixNumber db '@['
dwRowIn dw 0
db ','
dwColIn dw 0
db ']:$'
dwSize dw 0,0,0;3 dup(?)
ddArray dd 0[/code]
Единственное, на что ругался NASM, это не инициализированные переменные, пришлось "?" заменить на "0".

Удачи!
Прикрепленные файлы:
07a5dfed843026fd9018ec1056c082be881f2f21.jpg
5
Быстро и четко, что нужно объяснят. Огромное спасибо
Об авторе:
Мне безразлично, что Вы думаете о обо мне, но я рад за Вас - Вы начали думать.

давно
Старший Модератор
31795
6196
19.09.2017, 16:20
общий
Адресаты:
Забыл добавить - командная строка:
D:\CAT\_Lang\Nasm\nasm-2.10.09\nasm -f bin 170919.asm -o 170919a.com -l 170919a.lst
Об авторе:
Мне безразлично, что Вы думаете о обо мне, но я рад за Вас - Вы начали думать.

давно
Старший Модератор
31795
6196
19.09.2017, 16:32
общий
Адресаты:
Вычитал ещё одно условие:
Цитата: Kseniia
Подсчитать количество таких замен.

Исправил:
[code lang=asm h=250]org 100h
mov cx,3
mov di,ddArray
mov si,dwSize
@@01: call inputMatrix
add si,2
loop @@01
mov cx,3
mov di,ddArray
mov si,dwSize
@@02: call jobMatrix
add si,2
loop @@02
mov cx,3
mov di,ddArray
mov si,dwSize
@@03: call outputMatrix
add si,2
loop @@03
mov ah,9
mov dx,dbResult
int 21h
mov ax,[dwCount]
call outputNumber
xor ax,ax
int 16h
ret
inputMatrix:
inc byte[dbMatrixSize]
inc byte[dbMatrixNumber]
push cx
IM0: mov ah,9
mov dx,dbEnterSize
int 21h
call inputNumber
or ax,ax
jz IM0
mov [si],ax
mov cx,[si]
IM1: push cx
call convertNumber
mov [dwRowIn],ax
mov cx,[si]
IM2: call convertNumber
mov [dwColIn],ax
mov ah,9
mov dx,dbEnterNumber
int 21h
call inputNumber
stosd
loop IM2
pop cx
loop IM1
pop cx
ret
jobMatrix:
push cx
mov cx,[si]
JM1: mov bx,cx
mov cx,[si]
JM2: cmp bx,cx
jb JM3
mov eax,[di]
test eax,1
jnz JM3
xor eax,eax
mov [di],eax
inc word[dwCount]
JM3: add di,4
loop JM2
mov cx,bx
loop JM1
pop cx
ret
outputMatrix:
push cx
inc byte[dbMatrixName]
xor cx,cx
call convertNumber
mov [dwRowOut],ax
mov [dwColOut],ax
mov ah,9
mov dx,dbOutputMatrix
int 21h
mov cx,[si]
OM1: push cx
mov al,10
int 29h
mov al,13
int 29h
mov cx,[si]
OM2: mov eax,[di]
call outputNumber
add di,4
loop OM2
pop cx
loop OM1
pop cx
ret
inputNumber:
push di
xor edi,edi
mov ebx,10
IN1: xor ax,ax
int 16h
cmp al,13
jz IN2
cmp al,'0'
jb IN1
cmp al,'9'
ja IN2
int 29h
and eax,0Fh
xchg edi,eax
xor edx,edx
mul ebx
add edi,eax
jmp IN1
IN2: mov eax,edi
pop di
ret
outputNumber:
push cx
mov ebx,10
xor cx,cx
ON1: xor edx,edx
div ebx
push dx
inc cx
or eax,eax
jnz ON1
mov al,' '-30h
ON2: push ax
inc cx
cmp cx,6
jb ON2
ON3: pop ax
add al,30h
int 29h
loop ON3
pop cx
ret
convertNumber:
mov ax,[si]
sub ax,cx
aam
add ax,3031h
xchg al,ah
ret
dbEnterSize db 10,13,'Enter matrix '
dbMatrixSize db '@ size:$'
dbOutputMatrix db 10,10,13,'Output matrix '
dbMatrixName db '@['
dwRowOut dw 0
db ','
dwColOut dw 0
db ']:$'
dbEnterNumber db 10,13,'Enter value '
dbMatrixNumber db '@['
dwRowIn dw 0
db ','
dwColIn dw 0
db ']:$'
dbResult db 10,10,13,'Count change:$'
dwCount dw 0
dwSize dw 0,0,0;3 dup(?)
ddArray dd 0[/code]
Удачи!
Прикрепленные файлы:
2d56d500af4e867668b56502e6eadbfa.jpg
Об авторе:
Мне безразлично, что Вы думаете о обо мне, но я рад за Вас - Вы начали думать.

давно
Посетитель
399275
16
20.09.2017, 05:33
общий
20.09.2017, 05:43
Попробовать Nasm другой версии?
Прикрепленные файлы:
4939e44344645026b14b15010a5e7329.PNG
давно
Посетитель
399275
16
20.09.2017, 10:40
общий
и можно комментарии
давно
Старший Модератор
31795
6196
20.09.2017, 11:50
общий
Адресаты:
Вам нужен DOSBox, устанавливаете и запускаете. После запуска на экране будет Z:\>
набираете
mount d d:\nasm\
d:

запускаете свою программу
Об авторе:
Мне безразлично, что Вы думаете о обо мне, но я рад за Вас - Вы начали думать.

давно
Старший Модератор
31795
6196
20.09.2017, 15:44
общий
20.09.2017, 15:50
Адресаты:
Цитата: Kseniia
комментарии

В принципе комментировать нечего, программа в одинаковых циклах вызывает соответствующие подпрограммы inputMatrix(ввод размера текущей матрицы и её элементов), jobMatrix(выполняет задание) и outputMatrix(выводит матрицу).
[code lang=asm] mov cx,3;количество матриц
mov di,ddArray;адрес первого элемента первой матриц
mov si,dwSize;адрес размера первой матрицы
@@01: call inputMatrix;п/п-мма ввода матрицы
add si,2;переходим к следующаму размеру
loop @@01;цикл ввода матриц[/code]

Подпрограммы(inputMatrix, jobMatrix и outputMatrix). построены одинаково. Два вложенных цикла и действия подпрограммы:
[code lang=asm]subProgramm:
push cx;cохраняем используемый регистр
. . .;подготовка к внешнему циклу
mov cx,[si];загружаем кол-во строк
lab1: push cx;запоминаем их
. . .;подготовка к внутреннему циклу
mov cx,[si];загружаем кол-во столбцов
lab2:
. . .;действия подпрограммы
add di,4;переход к следующему элементу
loop lab2;цикл по столбцам
pop cx;востанавливаем параметр цикла по строкам
loop lab1;цикл по строкам
pop cx;востанавливаем регистр
ret;возврат из подпрограммы[/code]

Три оставшиеся подпрограммы, вызываются из программы и подпрограмм:
[code lang=asm h=250]inputNumber:;подпрограмма ввода числа
push di;запоминаем регистр
xor edi,edi;сбрасываем регистр
mov ebx,10;система счисления
IN1: xor ax,ax;ожидаем цифру
int 16h
cmp al,13;проверяем завершение ввода
jz IN2
cmp al,'0';проверяем цифру
jb IN1;не цифра переходим
cmp al,'9'
ja IN2
int 29h;выводим на экран
and eax,0Fh;выделяем цифру
xchg edi,eax;меняем введенную цифру с уже введенным числом
xor edx,edx
mul ebx;умножаем на СС
add edi,eax;суммируем
jmp IN1Продолжаем ввод
IN2: mov eax,edi;введенное число в ЕАХ
pop di;востанавливаем регистр
ret;выход из подпрограммы
outputNumber:;подпрограмма вывода числа
push cx
mov ebx,10
xor cx,cx;счетчик цифр в числе
ON1: xor edx,edx
div ebx;выделяем младшую цифру
push dx;запоминаем в стеке
inc cx;считаем их
or eax,eax;продолжаем пока не ноль
jnz ON1
mov al,' '-30h;потом это будет пробел
ON2: push ax;запоминаем его
inc cx;снова считаем
cmp cx,6;на число 6-ть пзиций
jb ON2
ON3: pop ax;извлекаем из стека в нужном порядке
add al,30h;преобразовываем в символ
int 29h;выводим
loop ON3;в цикле чистим стек
pop cx
ret
convertNumber:;преобразовываем число в символы
mov ax,[si];читаем текущий размер матрицы
sub ax,cx;текущиее значенение параметра цикла
aam;быстрое деление
add ax,3031h;преобразовываем в символ
xchg al,ah;меняем местами
ret;возврат из п/п-ммы[/code]

Попробуйте разобраться самостоятельно, моменты, которые Вам будут не понятны спрашивайте.
Об авторе:
Мне безразлично, что Вы думаете о обо мне, но я рад за Вас - Вы начали думать.

давно
Посетитель
399275
16
20.09.2017, 18:30
общий
C DosBoxом и комментариями я уже разобралась, а если отрицательные числа. Программа ведь их не поддерживает, как с ними быть?
Добавить дополнительную проверку на знак - (там где проверяем символ меньше '0' и больше '9') и потом использовать neg
давно
Старший Модератор
31795
6196
20.09.2017, 19:58
общий
Адресаты:
Цитата: Kseniia
, а если отрицательные числа.

тут есть вывод отрицательных
Где то был и ввод, но найти не могу
Об авторе:
Мне безразлично, что Вы думаете о обо мне, но я рад за Вас - Вы начали думать.

давно
Старший Модератор
31795
6196
25.09.2017, 11:05
общий
Ввод и вывод отрицательных
[code lang=asm h=200]inNum proc
push bx
push cx
push di
mov ax,bx
mov bx,maxX
xor dx,dx
div bx
inc al
add al,'0'
mov dbRow,al
mov ax,di
inc al
add al,'0'
mov dbCol,al
mov ah,9
lea dx,dbEnter
int 21h
xor si,si
xor di,di
mov bx,10
IN1: xor ah,ah
int 16h
cmp al,13
jz IN3
cmp al,'-'
jz IN2
cmp al,'0'
jb IN1
cmp al,'9'
ja IN1
int 29h
and ax,0fh
xchg di,ax
xor dx,dx
mul bx
test al,80h
jz INE
shl ax,1
INE: add di,ax
jmp short IN1
IN2: or di,di
jnz IN1
inc si
int 29h
jmp IN1
IN3: mov ax,di
or si,si
jz IN4
neg al
IN4: pop di
pop cx
pop bx
ret
inNum endp
;
outNum proc
push bx
push cx
push di
xor si,si
test ax,8000h
jz ON1
inc si
neg ax
ON1: mov bx,10
xor cx,cx
ON2: xor dx,dx
div bx
push dx
inc cx
or ax,ax
jnz ON2
or si,si
jz ON3
mov al,'-'-'0'
push ax
inc cx
ON3: mov al,' '-'0'
ON4: push ax
inc cx
cmp cx,8
jb ON4
ON5: pop ax
add al,'0'
int 29h
loop ON5
pop di
pop cx
pop bx
ret[/code]
Об авторе:
Мне безразлично, что Вы думаете о обо мне, но я рад за Вас - Вы начали думать.

Форма ответа