Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Низкоуровневое программирование > Assembler - Ассемблер (FASM, MASM, WASM, NASM, GoASM, Gas, RosAsm, HLA) и не рекомендуем TASM
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 11.04.2023, 11:05   #1
YaLubluMamu
Пользователь
 
Регистрация: 22.10.2022
Сообщений: 37
По умолчанию АРИФМЕТИЧЕСКИЕ ОПЕРАЦИИ НАД МАТРИЦАМИ

Подпрограмма суммирования слов, делящихся на 3, в четных столбцах.
Помогите, пожалуйста, исправить ошибки в коде:

Код:
; Подпрограмма суммирования слов с нечетными значениями в чётных столбцах.

nata segment 'code'
assume cs:nata, ds:nata, ss:nata, es:nata
org 100h
begin: jmp main
;------------Для ввода ---------------------
Buf db 7,7 DUP(?)
datev dw 0
mnoj dw ?
ps dw 10,13,'$'
N dw 3 ; количество строк
M dw 4 ; количество столбцов
bait_v_stoke dw ? ; количество байт в одной строке
N_M dw ? ; количество элементов в массиве
;------------Для вывода ---------------------
date dw ?
my_s db '+'
T_Th db ?
Th db ?
Hu db ?
Tens db ?
Ones db ?
;---------------------------------
X dw 12 DUP(?) ; Резервируем память под массив
svX db 10,13,'Enter elements X',10,13,'$'
svXXX db 10,13,'Array X:',10,13,'$'
ssum db 10,13,'Sum of items with odd values in even columns',10,13,'$'
Sum dw 0 ; сумма элементов
K db ? ; номер столбца
K1 db ? ; номер строки
;---------------------------------
main proc near
; ******* 1 – Считаем количество элементов в массиве ? N_M *****
mov ax, N
mov bx, M
imul bx
mov N_M,ax ; нашли количество элементов в массиве
; считаем сколько байт памяти занимает одна строка ?bait_v_stoke
mov ax,M
mov bx,2
imul bx
mov bait_v_stoke,ax ; количество байт в одной строке
; ******** 2 – Заполняем массив X ****************
mov cx, N_M ; количество элементов в массиве
lea si,X ; адрес первого элемента
@z1:
push cx

; выводим строку-подсказку
mov ah, 09
lea dx, svX
int 21h
; получаем один элемент
call vvod
; записываем его в массив
mov ax, datev
mov [si], ax
; переходим к следующему элементу, увеличивая индекс на 2
add si, 2
pop cx
loop @z1
; ******* 3 – Вывод массива X *****************
; Выводим строку МАССИВ X
mov ah,09
lea dx,svXXX
int 21h
; Выводим массив X построчно
mov cx,N ; внешний цикл – по количеству строк
mov bx,0 ; сколько байт до начала строки пропустить
; ------ внешний цикл по строкам ------------------------------------
@next_row:
push cx
mov cx, M ; M - количество элементов строки
mov si,0
; ---- внутренний цикл по элементам строки --------------
@next_elem:
mov ax, X[bx][si]
; вывод одного элемента строки
mov date,ax
push cx bx ; сохраняем в стеке нужные регистры
call vivod
pop bx cx
add si,2 ; переход к след. элементу строки
loop @next_elem
; ---- конец внутреннего цикла по элементам строки -----
add bx, bait_v_stoke ; переход к след. строке
mov ah,09 ; перевод строки
lea dx,ps
int 21h
pop cx
loop @next_row
; ------ конец внешнего цикла по строкам --------------
; ******** Конец вывода массива X *********************

;***** 4 – Вызов процедуры подсчета суммы ***************
call raschet_odd
; ***** 5 – Вывод значения суммы ************************
mov ah,09
lea dx,ssum
int 21h
mov ax,sum
mov date,ax
call vivod
; Ожидание нажатия на клавишу
mov ah,08
int 21h
ret
main endp
; ****** 6 – Вывод одного числа на экран *******************
vivod proc near
;--- Число отрицательное ?----------
mov ax,date
and ax,1000000000000000b
mov cl,15
shr ax,cl
cmp ax,1
jne @m1
mov ax,date
neg ax
mov my_s,'-'
jmp @m2
;--- Получаем десятки тысяч ---------------
@m1: mov ax,date
@m2: cwd
mov bx,10000
idiv bx
mov T_Th,al
;------- Получаем тысячи --------------------
mov ax,dx
cwd
mov bx,1000
idiv bx
mov Th,al
;------ Получаем сотни -----------------------
mov ax,dx
mov bl,100
idiv bl
mov Hu,al
;---- Получаем десятки и единицы ---------
mov al,ah
cbw

mov bl,10
idiv bl
mov Tens,al
mov Ones,ah
;--- Выводим знак -----------------------
cmp my_s,'+'
je @m500
mov ah,02h
mov dl,my_s
int 21h
;---------- Выводим цифры -----------------
@m500: cmp T_TH,0 ; проверка на ноль
je @m200
mov ah,02h ; выводим на экран, если не ноль
mov dl,T_Th
add dl,48
int 21h
@m200: cmp T_Th,0
jne @m300
cmp Th,0
je @m400
@m300: mov ah,02h
mov dl,Th
add dl,48
int 21h
@m400: cmp T_TH,0
jne @m600
cmp Th,0
jne @m600
cmp hu,0
je @m700
@m600: mov ah,02h
mov dl,Hu
add dl,48
int 21h
@m700: cmp T_TH,0
jne @m900
cmp Th,0
jne @m900
cmp Hu,0
jne @m900
cmp Tens,0
je @m950
@m900: mov ah,02h
mov dl,Tens
add dl,48
int 21h

@m950: mov ah,02h
mov dl,Ones
add dl,48
int 21h
mov ah,02h
mov dl,' '
int 21h
ret
vivod endp
; ***** 7 – Процедура ввод одного элемента массива *******
vvod proc near
mov datev,0
; ввод числа в виде строки символов
mov ah,10
lea dx,buf
int 21h
mov mnoj,1
; получаем количество введенных символов
mov cl,byte ptr buf+1 ; сколько символов(цифр)
mov ch,0
mov bp,cx
add bp,1 ; адрес последней цифры
@m1000:
; берем одну цифру
mov al,byte ptr buf+bp
sub al,30h
cbw
imul mnoj ; ax=цифра*10 в соответсвующей степени
add datev,ax
; умножаем множитель на 10
mov ax,10
imul mnoj
mov mnoj,ax
sub bp,1
loop @m1000
; перевод строки
mov ah,09
lea dx,ps
int 21h
ret
vvod endp
;***** 8 – Процедура подсчета суммы ***************************
; Подпрограмма суммирования слов с нечетными значениями в чётных столбцах и делящихся на 3
raschet_odd proc near
mov K, 0 ; начинаем с 0-го столбца
mov Sum, 0 ; инициализируем сумму нулем
@top:
cmp K, M ; если просмотрели все столбцы, то выходим из подпрограммы
je @exit
mov K1, 0 ; начинаем с 0-й строки
@next_col:
mov bx, X[K1][K] ; загружаем слово
test bx, 1 ; проверяем нечетность слова
jz @next_word ; если слово четное, переходим к следующему
add K1, 1 ; переходим к следующей строке
cmp K1, N ; если просмотрели все строки, то переходим к следующему столбцу
je @next_col
mov ax, bx ; проверяем деление на 3
mov dx, 0
mov cx, 3
div cx
cmp dx, 0 ; если не делится на 3, переходим к следующему слову
jne @next_word
add Sum, bx ; добавляем значение слова к сумме
@next_word:
add K1, 1 ; переходим к следующей строке
cmp K1, N ; если просмотрели все строки, то переходим к следующему столбцу
jne @next_col
add K, 2 ; переходим к следующему четному столбцу
jmp @top
@exit:
ret
raschet_odd endp

;***************************************************************
nata ends
end begin
YaLubluMamu вне форума Ответить с цитированием
Старый 11.04.2023, 11:53   #2
macomics
Участник клуба
 
Регистрация: 17.04.2022
Сообщений: 1,833
По умолчанию

Код:
; Подпрограмма суммирования слов с нечетными значениями в чётных столбцах.

nata segment 'code'
assume	cs:nata, ds:nata, ss:nata, es:nata
org	256
begin:	jmp	main
;------------Для ввода ---------------------
Buf		db 7,7 DUP(?)
datev		dw 0
mnoj		dw ?
N		dw 3 ; количество строк
M		dw 4 ; количество столбцов
bait_v_stoke	dw ? ; количество байт в одной строке
N_M		dw ? ; количество элементов в массиве
ps		db 10,13,'$',0
;------------Для вывода ---------------------
date		dw ?
my_s		db '+'
T_Th		db ?
Th		db ?
Hu		db ?
Tens		db ?
Ones		db ?
;---------------------------------
X		dw 12 DUP(?) ; Резервируем память под массив
K		db ? ; номер столбца
K1		db ? ; номер строки
Sum		dw 0 ; сумма элементов
svX		db 10,13,'Enter elements X',10,13,'$'
svXXX		db 10,13,'Array X:',10,13,'$'
ssum		db 10,13,'Sum of items with odd values in even columns',10,13,'$'
;---------------------------------
main proc near
; ! Необходимо однозначно настраивать сегментные регистры.
	mov	ax, cs	; т.к. у вас программа из одного сегмента
	mov	ds, ax	; значит записываем во все сегментные регистры
	mov	es, ax	; одно и тоже значение

	cld		; настройка работы строковых операций
; ******* 1 – Считаем количество элементов в массиве ? N_M *****
	mov	ax, N

;	mov	bx, M
;	imul	bx
	imul	M

	mov	N_M, ax ; нашли количество элементов в массиве
; считаем сколько байт памяти занимает одна строка ?bait_v_stoke
	mov	ax, M

;	mov	bx, 2
;	imul	bx
	add	ax, ax

	mov	bait_v_stoke, ax ; количество байт в одной строке
; ******** 2 – Заполняем массив X ****************
	mov	cx, N_M ; количество элементов в массиве
;	lea	si, X ; адрес первого элемента
	lea	di, X
  @z1:
	push	cx

; выводим строку-подсказку
	mov	ah, 09
	lea	dx, svX ; 10,13,'Enter elements X',10,13,'$'
	int	21h
; получаем один элемент
	call	vvod
; записываем его в массив
;	mov	ax, datev ; Это значение можно сразу записать в ax вконце подпрограммы vvod

;	mov	[si], ax  ; Тут можно обойтись строковой командой, которая заменит сразу 2 команды
; переходим к следующему элементу, увеличивая индекс на 2
;	add	si, 2
	stosw

	pop	cx
	loop	@z1
; ******* 3 – Вывод массива X *****************
; Выводим строку МАССИВ X
	mov	ah, 09
	lea	dx, svXXX ; 10,13,'Array X:',10,13,'$'
	int	21h
; Выводим массив X построчно
	mov	cx, N ; внешний цикл – по количеству строк
	mov	bx, 0 ; сколько байт до начала строки пропустить
; ------ внешний цикл по строкам ------------------------------------
  @next_row:
	push	cx
	mov	cx, M ; M - количество элементов строки

;	mov	si, 0
	lea	si, X[bx]
	
; ---- внутренний цикл по элементам строки --------------
  @next_elem:
;	mov	ax, X[bx][si]
;	add	si, 2 ; переход к след. элементу строки
	lodsw
	
; вывод одного элемента строки
	mov	date, ax
	push	cx bx ; сохраняем в стеке нужные регистры
	call	vivod
	pop	bx cx
	loop	@next_elem
; ---- конец внутреннего цикла по элементам строки -----
	add	bx, bait_v_stoke ; переход к след. строке
	mov	ah, 09 ; перевод строки
	lea	dx, ps ; 10,13,'$'
	int	21h
	pop	cx
	loop	@next_row
; ------ конец внешнего цикла по строкам --------------
; ******** Конец вывода массива X *********************

;***** 4 – Вызов процедуры подсчета суммы ***************
	call	raschet_odd
; ***** 5 – Вывод значения суммы ************************
	mov	ah, 09
	lea	dx, ssum ; 10,13,'Sum of items with odd values in even columns',10,13,'$'
	int	21h
	mov	ax, sum
	mov	date, ax
	call	vivod
; Ожидание нажатия на клавишу
	mov	ah, 08
	int	21h

; !Программа завершается через вызов соответствующей функции, а не по команде ret
	ret
	mov	ax, 4C00h
	int	33
main endp

; ****** 6 – Вывод одного числа на экран *******************
; Эту подпрограмму можно скопировать из предыдущей темы
; https://www.programmersforum.ru/show...05&postcount=4
vivod proc near
;--- Число отрицательное ?----------
mov ax,date
and ax,1000000000000000b
mov cl,15
shr ax,cl
cmp ax,1
jne @m1
mov ax,date
neg ax
mov my_s,'-'
jmp @m2
;--- Получаем десятки тысяч ---------------
@m1: mov ax,date
@m2: cwd
mov bx,10000
idiv bx
mov T_Th,al
;------- Получаем тысячи --------------------
mov ax,dx
cwd
mov bx,1000
idiv bx
mov Th,al
;------ Получаем сотни -----------------------
mov ax,dx
mov bl,100
idiv bl
mov Hu,al
;---- Получаем десятки и единицы ---------
mov al,ah
cbw

mov bl,10
idiv bl
mov Tens,al
mov Ones,ah
;--- Выводим знак -----------------------
cmp my_s,'+'
je @m500
mov ah,02h
mov dl,my_s
int 21h
;---------- Выводим цифры -----------------
@m500: cmp T_TH,0 ; проверка на ноль
je @m200
mov ah,02h ; выводим на экран, если не ноль
mov dl,T_Th
add dl,48
int 21h
@m200: cmp T_Th,0
jne @m300
cmp Th,0
je @m400
@m300: mov ah,02h
mov dl,Th
add dl,48
int 21h
@m400: cmp T_TH,0
jne @m600
cmp Th,0
jne @m600
cmp hu,0
je @m700
@m600: mov ah,02h
mov dl,Hu
add dl,48
int 21h
@m700: cmp T_TH,0
jne @m900
cmp Th,0
jne @m900
cmp Hu,0
jne @m900
cmp Tens,0
je @m950
@m900: mov ah,02h
mov dl,Tens
add dl,48
int 21h

@m950: mov ah,02h
mov dl,Ones
add dl,48
int 21h
mov ah,02h
mov dl,' '
int 21h
ret
vivod endp
; ***** 7 – Процедура ввод одного элемента массива *******
; Эту подпрограмму можно скопировать из предыдущей темы
; https://www.programmersforum.ru/show...05&postcount=4
vvod proc near
mov datev,0
; ввод числа в виде строки символов
mov ah,10
lea dx,buf
int 21h
mov mnoj,1
; получаем количество введенных символов
mov cl,byte ptr buf+1 ; сколько символов(цифр)
mov ch,0
mov bp,cx
add bp,1 ; адрес последней цифры
@m1000:
; берем одну цифру
mov al,byte ptr buf+bp
sub al,30h
cbw
imul mnoj ; ax=цифра*10 в соответсвующей степени
add datev,ax
; умножаем множитель на 10
mov ax,10
imul mnoj
mov mnoj,ax
sub bp,1
loop @m1000
; перевод строки
mov ah,09
lea dx,ps
int 21h
ret
vvod endp
;***** 8 – Процедура подсчета суммы ***************************
; Подпрограмма суммирования слов с нечетными значениями в чётных столбцах и делящихся на 3
raschet_odd proc near
	push	bx si di

;	mov	K, 0
	xor	si, si	; начинаем с 0-го столбца
	mov	Sum, 0	; инициализируем сумму нулем
  @top:

;	cmp	K, M
	cmp	si, M	; если просмотрели все столбцы, то выходим из подпрограммы

	je	@exit

;	mov	K1, 0
	xor	bx, bx	; начинаем с 0-й строки

  @next_col:

;	mov	bx, X[K1][K]
	mov	ax, X[bx][si] ; загружаем слово

	test	al, 1 ; проверяем нечетность слова
	jz	@next_word ; если слово четное, переходим к следующему

;	add	K1, 1
	add	bx, bait_v_stoke 	; переходим к следующей строке

;	cmp	K1, N
	cmp	bx, M_N	; если просмотрели все строки, то переходим к следующему столбцу

	jc	@next_col
	jmp	@exit_inner_loop

;	mov	ax, bx
	mov	di, ax	; проверяем деление на 3

; А где в задании проверка на кратность 3-м?
; Но я и её поправил
	mov	dx, 0
	mov	cx, 3
	div	cx
	cmp	dx, 0 ; если не делится на 3, переходим к следующему слову
	jne	@next_word
	add	Sum, di ; добавляем значение слова к сумме
  @next_word:

	add	K1, 1
	add	bx, bait_v_stoke ; переходим к следующей строке

	cmp	K1, N
	cmp	bx, M_N ; если просмотрели все строки, то переходим к следующему столбцу
	jne	@next_col
  @exit_inner_loop:

	add	si, 2 ; переходим к следующему четному столбцу
	jmp	@top

  @exit:
	pop	di si bx
	ret
raschet_odd endp

;***************************************************************
nata ends
end begin

Последний раз редактировалось macomics; 11.04.2023 в 11:57.
macomics вне форума Ответить с цитированием
Старый 11.04.2023, 12:00   #3
macomics
Участник клуба
 
Регистрация: 17.04.2022
Сообщений: 1,833
По умолчанию

И, пожалуйста, выравнивайте код. Так его читать будет вам же проще.
macomics вне форума Ответить с цитированием
Старый 11.04.2023, 13:12   #4
YaLubluMamu
Пользователь
 
Регистрация: 22.10.2022
Сообщений: 37
По умолчанию

Хорошо. Спасибо большое
YaLubluMamu вне форума Ответить с цитированием
Старый 11.04.2023, 22:25   #5
digitalis
Старожил
 
Аватар для digitalis
 
Регистрация: 04.02.2011
Сообщений: 4,550
По умолчанию

И набирать название темы ПРОПИСНЫМИ буквами - всё равно, что КРИЧАТЬ в обычном разговоре.
digitalis вне форума Ответить с цитированием
Старый 12.04.2023, 10:00   #6
YaLubluMamu
Пользователь
 
Регистрация: 22.10.2022
Сообщений: 37
По умолчанию

Цитата:
Сообщение от macomics Посмотреть сообщение
cmp bx, M_N
Можно еще вопрос? Что такое M_N?
YaLubluMamu вне форума Ответить с цитированием
Старый 12.04.2023, 11:24   #7
macomics
Участник клуба
 
Регистрация: 17.04.2022
Сообщений: 1,833
По умолчанию

Цитата:
Сообщение от YaLubluMamu Посмотреть сообщение
Можно еще вопрос?
Можно

Цитата:
Сообщение от YaLubluMamu Посмотреть сообщение
Что такое M_N?
Очепятка
macomics вне форума Ответить с цитированием
Старый 12.04.2023, 16:33   #8
YaLubluMamu
Пользователь
 
Регистрация: 22.10.2022
Сообщений: 37
По умолчанию

Прошу прощения, но есть еще одна проблемка. Почему введенные значения не сохраняются в массив?
YaLubluMamu вне форума Ответить с цитированием
Старый 12.04.2023, 17:46   #9
macomics
Участник клуба
 
Регистрация: 17.04.2022
Сообщений: 1,833
По умолчанию

Об этом было написано в комментариях. Я просто убрал строчку
Код:
;	mov	ax, datev ; Это значение можно сразу записать в ax вконце подпрограммы vvod
Её надо поместить в конце подпрограммы vvod
Код:
vvod proc near
	push	bp bx si
	mov	bp, 0
; ввод числа в виде символов
	mov	ah, 0ah
	lea	dx, buf
	int	21h
; получаем количество введенных символов
	lea	si, buf+2
	mov	bx, 10 ; 1
	mov	cl, byte ptr buf+1 ; сколько символов(цифр)
	mov	ch, 0
;	add	bp, cx
;	add	bp, 1 ; адрес последней цифры

	cmp	byte ptr [si], '-'
	jne	@m1000
	inc	si

  @m1000:
; берем одну цифру
	mov	al, byte ptr [bx]; buf+bp
	lodsb

	sub	al, 30h
	cbw
	xchg	ax, bp
	mul	bx ; ax=bp*10; цифра*10^
	add	bp, ax

; умножаем множитель на 10
;	[S]mov	ax, 10[S]
;	[S]imul	mnoj[S]
;	[S]mov	mnoj, ax[S]
;	[S]sub	bp, 1[S]

	loop	@m1000
	cmp	byte ptr Buf[2], '-'
	jne	@m1001
	neg	bp

  @m1001:
	mov	ah, 09
	lea	dx, ps
	int	21h
	mov	ax, bp
	pop	si bx bp
	ret
vvod endp
В таком варианте теперь не нужны глобальные переменные mnoj и datev

Последний раз редактировалось macomics; 12.04.2023 в 17:53.
macomics вне форума Ответить с цитированием
Старый 13.04.2023, 09:51   #10
YaLubluMamu
Пользователь
 
Регистрация: 22.10.2022
Сообщений: 37
По умолчанию

Надеюсь, что это последний вопрос. Почему результат сложения не выводится?
YaLubluMamu вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Арифметические операции nikita-92 Assembler - Ассемблер (FASM, MASM, WASM, NASM, GoASM, Gas, RosAsm, HLA) и не рекомендуем TASM 0 11.04.2013 00:08
Арифметические операции. Saintpatrick38 Помощь студентам 2 05.04.2013 09:04
Арифметические операции swillrocker Assembler - Ассемблер (FASM, MASM, WASM, NASM, GoASM, Gas, RosAsm, HLA) и не рекомендуем TASM 2 02.10.2012 21:31
Арифметические действия над матрицами и транспонирование Axel1981 Помощь студентам 14 12.06.2010 20:20