Отправляет email-рассылки с помощью сервиса Sendsay
  Все выпуски  

RFpro.ru: Ассемблер? Это просто! Учимся программировать


РАССЫЛКИ ПОРТАЛА RFPRO.RU

Лучшие эксперты по данной тематике

Асмик Гаряка
Статус: Советник
Рейтинг: 11034
∙ повысить рейтинг »
Коцюрбенко Алексей aka Жерар
Статус: Советник
Рейтинг: 4356
∙ повысить рейтинг »
Куликов Роман Евгеньевич
Статус: 1-й класс
Рейтинг: 0
∙ повысить рейтинг »

/ КОМПЬЮТЕРЫ И СОФТ / Программирование / Assembler (Ассемблер)

Номер выпуска:1569
Дата выхода:16.10.2015, 10:51
Администратор рассылки:Лысков Игорь Витальевич (Старший модератор)
Подписчиков / экспертов:16 / 7
Вопросов / ответов:1 / 1

Консультация # 188099: Здравствуйте! Прошу помощи в следующем вопросе: Помогите,пожалуйста решить задачи в Ассемблере. Я в нем полный ноль.Завтра сдать надо,а я представления не имею как...(( 1. Найти максимальный элемент, делящийся на 3. 2.Дано целое число N (> 1). Если оно является недостаточным, то есть сумма положительных делителей, кроме сам...


Консультация # 188099:

Здравствуйте! Прошу помощи в следующем вопросе:
Помогите,пожалуйста решить задачи в Ассемблере. Я в нем полный ноль.Завтра сдать надо,а я представления не имею как...((


1. Найти максимальный элемент, делящийся на 3.
2.Дано целое число N (> 1). Если оно является недостаточным, то есть сумма положительных
делителей, кроме самого себя, меньше N, то вывести True, иначе вывести False.
3.Дана строка и число n. Верно ли, что в ней есть по крайней мере n подряд идущих букв a?

Дата отправки: 13.10.2015, 10:33
Вопрос задал: Попушой Екатерина (Посетитель)
Всего ответов: 1
Страница онлайн-консультации »


Консультирует Лысков Игорь Витальевич (Старший модератор):

Здравствуйте, Попушой Екатерина Витальевна!
Программы под компилятор FASM, формируют COM-файл
1) Программа читает из определенной в тексте все числа, проверяет их на делимость на 3 и ищет среди них максимальный
Затем выводится найденное число, десятичные разряды которого находятся делением на 10 и сохранением в стеке.

Код :
;Найти максимальный элемент, делящийся на 3
	use16
	org    100h
	lea		bx, [numbers]	;строка чисел
	mov		cx, 5	;их количество
	call	FindMaxDiv3		;ищем требуемое число в последовательности чисел, результат в регистре AX
							;AX = 0, если таких чисел нет
	lea		dx, [sNum]		;заголовок сообщения
	call	PrintNum		;выводим число
	
	lea		dx, [sPress]	;сообщение нажать любую клавишу
	mov		ah, 9			;функция вывода строки
	int		21h

	mov		ah, 0			;ждем нажатие на клавишу
	int		16h
	
	mov		ax, 4c00h
	int		21h				;выход из программы
	
;разбор строки и поиск максимального числа, делящегося на 3, 
;адрес массива чисел в регистре BX, количество в CX
;вернет в регистре AX (= 0, если таких чисел нет)
FindMaxDiv3:
	xor		si, si		;здесь будет искомое число
FindMaxDiv3_loop:
	mov		ax, [bx]	;берем очередное число
	inc		bx			;смещаем адрес для следующего
	inc		bx
	
	call	CmpMaxDiv3	;проверяем
	
	loop	FindMaxDiv3_loop	;и по всем
	mov		ax, si		;найденное число возвращаем в AX
	ret

CmpMaxDiv3:				;поиск максимального из делещихся на 3
	mov		bp, 3		;будем делить на 3
	xor		dx, dx		;подготавливаем делимое, т.к. будем делить DX:AX / BP
	push	ax			;сохраним само число
	div		bp			;делим, DX - остаток, AX - частное
	pop		ax			;восстановим число
	test	dx, dx		;проверим остаток, =0 - делится нацело
	jnz		CmpMaxDiv3_ret	;нет, это число нам неинтересно
	cmp		ax, si		;делится - ищем максимальное
	jb		CmpMaxDiv3_ret	;у нас уже есть большее
	mov		si, ax		;сохраним, как новое максимальное
CmpMaxDiv3_ret:
	ret

PrintNum:				;вывод числа из AX в виде последовательности цифр
	push	ax			;сохраним число, чтобы вывести заголовок
	mov		ah, 9		;выведем строку-заголовок, адрес в dx
	int		21h
	pop		ax

	test	ax, ax		;проверим, "а был ли мальчик"
	jne		PrintNum_continue	;был! на вывод числа!

	lea		dx, [sNotFound] 	  ;таких чисел нет!
	mov		ah, 9				;выводим сообщение
	int		21h
	ret							; и выходим
	
PrintNum_continue:		;продолжаем вывод
	mov		bp, 10		;будем делить на 10
	xor		cx, cx		;счетчик цифр
div_loop:				;цикл получения десятичных разрядов
	xor		dx, dx		;подготовимся для очередного деления
	div		bp			;в dx остаток - очередной десятичный разряд
	push	dx			;сохраним в стеке (от младшего к старшему)
	inc		cx			;посчитаем
	test	ax, ax		;есть еще десятичные разряды?
	jnz		div_loop	;продолжим

pr_loop:				;цикл вывода десятичных цифр-символов
	pop		dx			;востановим очередной разряд (от старшего к младшему)
	add		dl, '0' 	;символ цифры
	mov		ah, 2		;выведем
	int		21h			;
	loop	pr_loop 	;по всем цифрам
	ret
	
;
sNumbers	db	0dh,0ah,"Enter numbers: $"
sNum		db	0dh,0ah,"Maximum number, divided by 3: $"
sPress		db	0dh,0ah,"Press any key$"
sNotFound	db	"not found$"
numbers 	dw	123, 432, 32111, 11136, 57345

2) Должно быть все понятно из комментариев
Код :
;Дано целое число N (> 1). Если оно является недостаточным, то есть сумма положительных 
;делителей, кроме самого себя, меньше N, то вывести True, иначе вывести False.
	use16
	org    100h
	mov		AX, N			;исходное число

	call	CalcNum 		;считаем суму делителей, число и результат в AX

	lea		dx, [sTrue]		;сначала считаем, что True
	cmp		ax, N			;проверяем условие
	jb		print_str		;если меньше, то остается True
	lea		dx, [sFalse]	;иначе False

print_str:					;выводим
	mov		ah, 9			;функция вывода строки
	int		21h

	mov		ah, 0			;ждем нажатие на клавишу
	int		16h
	
	mov		ax, 4c00h
	int		21h				;выход из программы

CalcNum:					;считаем суму делителей, число и результат в AX
							;искать будем, проверяя, делится ли число на все числа
							;большие 2 и меньшие половины исходного
	mov		bx, 1			;сумма делителей, 1 будет всегда
	mov		cx, 1			;начальный делитель
	mov		di, ax
	shr		di, 1			;максимальный делитель (N/2)
CalcNum_loop:				;цикл поиска
	inc		cx				;увеличиваем делитель
	cmp		cx, di			;дошли до края?
	jae		CalcNum_ret
	xor		dx, dx			;готовимся к делению
	push	ax				;сохраним исходное число
	div		cx				;делим DX:AX/CX
	pop		ax				;восстановим исходное число
	test	dx, dx			;проверяем остаток
	jnz		CalcNum_loop	;не делится нацело - обходим
	add		bx, cx			;складываем делители
CalcNum_ret:
	mov		ax, bx			;результат в AX
	ret
	
N			dw	2364	
sTrue		db	0dh,0ah,"True$"
sFalse		db	0dh,0ah,"False$"
sPress		db	0dh,0ah,"Press any key$"

3) Ну и третья...
Код :
;Дана строка и число n. Верно ли, что aв ней есть по крайней мере n подряд идущих букв a

	use16
	org  100h
	lea	si, [string]		;исходное строка
	mov	dx, [n]			;число n
	mov	bl, 'a'			;искомый символ

	call	CalcStr 			;проверяем строку, результат в AX=1(верно) или =0(неверно)

	lea	dx, [sYes]		;сначала считаем, что верно
	cmp	ax, 1			;проверяем условие
	je	print_str			;если меньше, то остается Yes
	lea	dx, [sNo]			;иначе No

print_str:				;выводим
	mov	ah, 9			;функция вывода строки
	int	21h

	mov	ah, 0			;ждем нажатие на клавишу
	int	16h
	
	mov	ax, 4c00h
	int	21h				;выход из программы

;проверяем строку, результат в AX=1(верно) или =0(неверно)
;параметры: si - адрес строки, dx - число n, bl - символ
CalcStr:
	xor	cx, cx			;обнулим счетчик подряд идущих символов bl
CalcStr_loop:				;цикл по символам строки
	lodsb				;читаем очередной в al=ds:[si] с автоинкрементом si
	cmp	al, 0			;строка заканчивается нулем
	je	ret_no			;дошли до конца, значит n подряд идущих символов не нашли
	cmp	al, bl			;сравниваем текущий символ с искомым
	jne	CalcStr			;не равен - продолжаем поиск, обнуляя счетчик
	inc	cx				;равен - считаем
	cmp	cx, dx			;и сравниваем с числом n
	jb	CalcStr_loop		;меньше - смотрим дальше
	mov	ax, 1			;больше или равно - нашли n подряд идущих символа bl
	ret
ret_no:					;не нашли - возвращаем 0
	xor	ax, ax
	ret
	
n		dw	3	
string	db	'asdfgaakkkkaaallll',0
sYes		db	0dh,0ah,"Yes$"
sNo		db	0dh,0ah,"No$"
sPress	db	0dh,0ah,"Press any key$"

Консультировал: Лысков Игорь Витальевич (Старший модератор)
Дата отправки: 13.10.2015, 18:51

5
нет комментария
-----
Дата оценки: 14.10.2015, 07:05

Рейтинг ответа:

НЕ одобряю +2 одобряю!


Оценить выпуск | Задать вопрос экспертам

главная страница  |  стать участником  |  получить консультацию
техническая поддержка  |  восстановить логин/пароль

Дорогой читатель!
Команда портала RFPRO.RU благодарит Вас за то, что Вы пользуетесь нашими услугами. Вы только что прочли очередной выпуск рассылки. Мы старались. Пожалуйста, оцените его. Если совет помог Вам, если Вам понравился ответ, Вы можете поблагодарить автора - для этого в каждом ответе есть специальные ссылки. Вы можете оставить отзыв о работе портале. Нам очень важно знать Ваше мнение. Вы можете поближе познакомиться с жизнью портала, посетив наш форум, почитав журнал, который издают наши эксперты. Если у Вас есть желание помочь людям, поделиться своими знаниями, Вы можете зарегистрироваться экспертом. Заходите - у нас интересно!
МЫ РАБОТАЕМ ДЛЯ ВАС!


В избранное