;prg_14_3.asm
MASM
MODEL	small	;модель памяти
STACK	256	;размер стека
include	iomac.inc	;подключение файла с макросами
.data		;начало сегмента данных
maskd	db	71h	;маска вывода на экран
string	db	'Строка для подсчета $'	;тестовая строка
mes	db	'В строке string '
cnt	db	2 dup ('*')	; количество символов в строке
	db	' символов',10,13,'$'

.code
main	proc	;точка входа в главную процедуру
	mov	ax,@data
	mov	ds,ax
;загрузка адреса строки
;(для передачи смещения в процедуру)
	lea	si,string
;вызов процедуры
	call	CountSymbol
	mov	cl,bl	;счетчик для lods и stosw
	lea	si,string	;в si - указатель на строку
	mov	ax,0b800h
	mov	es,ax	;загрузка в es адреса видеопамяти
	mov	ah,maskd	;маска вывода на экран
	mov	di,160	;позиция вывода на экран
	cld		;просмотр вперед - для lodsb и stosw
disp:
	lodsb		;пересылка байта из ds:si в al
	stosw		;копирование значения ax
			;в es:di (видеобуфер)
	loop	disp	;повтор цикла cx раз
;а теперь выведем количество символов в строке
	mov	al,bl
	aam		;в al две упакованные BCD-цифры
			;результата подсчета
	or	ax,3030h	;преобразование результата в код ASCII
	mov	cnt,ah
	mov	cnt+1,al
	_OutStr	mes	;вывод строки mes
exit:
	_Exit		;макрос выхода
main	endp	;конец главной процедуры

CountSymbol	proc	near
;процедура CountSymbol - подсчёт символов в строке.
;На входе: si - смещение строки
;На выходе: bl - длина в виде упакованного BCD-числа
	push	ax;сохранение используемых регистров
	push	cx
	cld		;просмотр вперед
	mov	cx,100	;максимальная длина строки
;блок подсчёта символов
go:
	lodsb	;загрузка символа строки в al
	cmp	al,'$'
	je	endstr
	jcxz	no_end
	inc	bl	;приращение счетчика в bl - количества
			;подсчитанных символов в строке
	loop	go	;повтор цикла
endstr:		;конец строки
	pop	cx	;восстановление регистров из стека
	pop	ax
	ret	;возврат из процедуры
no_end:
;какие-то действия по обработке ситуации
;отсутствия в строке символа $
ret	;возврат из процедуры
CountSymbol	endp	;конец процедуры
	end	main	;конец программы

