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

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


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

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

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

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

Номер выпуска:1568
Дата выхода:14.10.2015, 19:51
Администратор рассылки:Лысков Игорь Витальевич (Старший модератор)
Подписчиков / экспертов:15 / 8
Вопросов / ответов:1 / 1

Консультация # 188084: Здравствуйте! У меня следующая задача: По запросу программы пользователь вводит с клавиатуры последовательность целых трехзначных положитель- ных десятичных чисел, разделенных пробелами. Ввод последова- тельности заканчивается нажатием <Enter>. Программа выводит последовательность этих же чисел, но записанных в обратном ...


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

Здравствуйте! У меня следующая задача:

По запросу программы пользователь вводит с
клавиатуры последовательность целых трехзначных положитель-
ных десятичных чисел, разделенных пробелами. Ввод последова-
тельности заканчивается нажатием <Enter>.
Программа выводит последовательность этих же чисел, но
записанных в обратном порядке и в шестнадцатеричной системе
счисления.

Если хоть кто-то чем-нибудь поможет уже будет здорово! smile

Дата отправки: 06.10.2015, 19:15
Вопрос задал: Евгения (Посетитель)
Всего ответов: 1
Страница онлайн-консультации »


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

Здравствуйте, Евгения!
Держите программу. Постарался максимально прокомментировать в тексте.
Сама постановка задачи, вывод в обратном порядке, наталкивает на мысль
хранить числа в стеке. Что и было сделано smile
Будут вопросы - пишите в мини-форум...

Код :
	.model	tiny
	.code
	.startup

	call	GetString		;вводим строку с числами
	call	GetNumbers		;разбираем строку и выводим числа в виде hex и в обратном порядке

	lea		dx, sPress		;сообщение нажать любую клавишу
	mov		ah, 9			;функция вывода строки
	int		21h

	mov		ah, 0			;ждем нажатие на клавишу
	int		16h
	
	.exit	0				;выход из программы (эквивалентно mov ax, 4c00h / int 21h)
	
;ввод строки с консоли
GetString	proc
	lea		dx, sNumbers	;сообщение 'Enter Numbers: '
	mov		ah,9
	int		21h

	lea		dx, InputString	;адрес параметра функции ввода строки (формат описан ниже)
	mov		ah, 0ah			;номер функции ввода строки
	int		21h
	ret
GetString	endp

;разбор строки и вывод результата
;числа будем хранить в стеке, чтобы вывести их в обратном порядке!
GetNumbers	proc
	mov		bp, 10		;будем умножать на 10 (при преобразовании строки в число)
	xor		cx, cx		;счетчик введенных чисел (хранятся в стеке)
	
	lea		si, InputString+2	;адрес самой строки 
						;+2, т.к. в первых двух байтах длина строки и число введенных символов
						;длину строки не используем, строку будем анализировать до кода конца строки (0dh)
num_loop:				;цикл формирования очередного числа
	xor		bx, bx		;здесь будем накапливать число
	xor		di, di		;счетчик цифр очередного числа, 
						; т.о. если =0, то числа нет (для контроля лишних пробелов)
sym_loop:				;цикл преобразования числовой строки в число
	lodsb				;читаем очередной байт в регистр al из ds:[si], автоинкремент si
;анализируем байт
	cmp		al, 0dh		;прошли до конца строки?
	je		cmp_last	;да, учтем последнее число из строки

	cmp		al, ' '		;пробел?
	je		space_found	;или конец введенного числа, или дополнительные разделители, 
						; которые проигнорируем
	
						;ждем только цифры '0' <= al <= '9'
	cmp		al, '0'		;проверим на цифру
	jb		sym_loop	;нецифры игнорируем
	cmp		al, '9'
	ja		sym_loop

	inc		di			;есть очередная цифра, считаем, чтобы знать, что что-то есть
						;вдвинем в формируемое число введенный десятичный разряд
						;для этого предыдущие разряды умнодим на 10 и сложим с введенным
	xchg	ax, bx		;ax = предыдущим разрядам, bx = введенной цифре
	mul		bp			;dx:ax = предыдущим старшим разрядам * 10
	and		bx, 000fh	;превратим символ цифры 30h-39h в число 0-9
	add		bx, ax		;bx = введенному числу (на данный момент)

	jmp		sym_loop	;повторяем анализ символов строки

space_found:			;встретили пробел
	test	di, di		;есть число?
	jz		sym_loop	;нет - дополнительные пробелы игнорируем
	
	push	bx			;число сохраняем в стеке!
	inc		cx			;считаем
	
	jmp		num_loop	;на формирование следующего числа

cmp_last:				;встретили 0dh-конец строки
	test	di, di		;проверим, было ли у нас сформировано число
	jz		output_hex	;если в конце строки есть пробелы, то счетчик di=0
						;если строка заканчивается цифрой, то di не равен 0
						;и тогда это последнее число также надо сохранить в стеке
	push	bx			;в стек!
	inc		cx			;считаем
		
output_hex:				;выводим результат
	lea		dx, sHex	;сообщение 'Hex values: '
	mov		ah,9
	int		21h

	mov		si, cx		;счетчик введенных чисел в si

hex_loop:				;цикл вывода hex-значений
	test	si, si		;проверим на 0 
	jnz		hex_continue
	ret					;все выведено или не было ни одного - выходим!
	
hex_continue:			;продолжаем вывод
	pop		bp			;извлекаем из стека очередного числа 
						;(в обратном порядке! так работает стек!)
	mov		cx, 4		;счетчик hex-цифр
form_hex_loop:			;цикл вывода hex-цифр, начиная со старшей
	rol		bp, 1		;циклически сдвигаем 4 раза, чтобы старшие 4 бита
	rol		bp, 1		;(старшая hex-цифра) попали на мели младших бит
	rol		bp, 1
	rol		bp, 1
	mov		bx, bp		;получаем код очередной цифры в младших битах
	and		bx, 0fh		;маскируем все остальные биты
	mov		dl, byte ptr Hex[bx]	;получаем символ hex-цифры из строки Hex
	mov		ah, 2		;и выводим на экран
	int		21h
	loop	form_hex_loop	;по всем 4 цифрам

	mov		dl, ' '		;разделим числа пробелом
	mov		ah, 2
	int		21h

	dec		si			;уменьшим счетчик чисел
	jmp		hex_loop	;и на повтор

GetNumbers	endp
	
;
Hex			db	'0123456789ABCDEF'
sNumbers	db	0dh,0ah,"Enter numbers: $"
sHex		db	0dh,0ah,"Hex values: $"
sPress		db	0dh,0ah,"Press any key$"
InputString	db	128,0,128 dup(?)

	end

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

5
Комментарии к исходному коды превосходны! Все вопросы отпадают. Спасибо-спасибо огромное! Я у Вас в должниках!
-----
Дата оценки: 07.10.2015, 17:41

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

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


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

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

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


В избранное