Главная Обратная связь

Дисциплины:






Вывод символьной строки. Модуль puts



Функция puts предназначена для вывода символьной строки на экран в текстовом режиме работы видеоадаптера. При вызове этой функции необходимо в качестве параметра передать адрес выводимой строки. При этом используются соглашения, принятые для языка Си. В функции предусмотрена возможность перехода на следующую строку. Для этого в выводимой строке необходимо включить комбинацию символов “\n”, точно также как это делается в функции printf языка Си.

Блок-схема программы представлена на рис. 2. 1.

Число строк и столбцов можно определить из области данных BIOS для EGA/VGA, которая находится в фиксированной области памяти, расположенной в диапазоне адресов от 0000:0410 до 0000:0500. Слово по адресу 0000:044a содержит число символов в строке -1, а байт 0000:0484 число текстовых строк-1.

Для получения номера текущей активной страницы используем функцию 0fh прерывания int 10h. Эта функция позволяет определить номер

 

текущего режима работы видеоадаптера, номер активной страницы и количество символов в строке экрана. Формат функции имеет следующий вид:

На входе: ah= 0fh- определение текущего режима видеоадаптера.

На выходе: ah= число символов в строке;

al = номер текущего режима;

bh= номер активной страницы видеопамяти.

 

Рис. 2.1. Блок-схема программы puts.

 

 

 


При выводе часто необходимо управлять положением курсора. Для этого надо определить его текущее положение. Для этого можно воспользоваться функцией 03h BIOS. Функция имеет следующий формат:

На входе: ah = 03h;

bh = номер страницы видеопамяти.

На выходе: ch = верхняя граница курсора;

cl = нижняя граница курсора;

dh = позиция текущей строки курсора;

dl = позиция текущего столбца курсора.

В приведенной программе для определения координат курсора используется функция 03h прерывания int 10h.

При обнаружении комбинации “\n” реализуется переход на следующую строку. Для этого используется функция 02h BIOS. Эта функция имеет формат:

На входе: ah = 02h;

bh = номер страницы видеопамяти;

dh = номер строки (0 - 24);

dl = номер столбца (0 - 79).

На выходе: Не используется.

Предварительно определяется наличие свободной строки на экране дисплея. Если свободного места нет, проводиться свертка текстового окна вверх. Для той цели используется функция 06h BIOS, имеющей формат:

На входе: ah = 06h;

al = число, прокручиваемых линий; если оно равно нулю, то окно прокручивается целиком.

bh = атрибут для строк, возникающих снизу окна;

ch = номер строки верхнего левого угла окна;

cl = номер столбца верхнего левого угла окна;



dh = номер строки нижнего правого угла окна;

dl = номер столбца нижнего правого угла окна.

На выходе: Не используется.

В программе для вывода символов на экран использована функция 0ah прерывания int 10h, которая записывает символ в текущей позиции курсора. При этом атрибуты символа не задаются, а используются их старые значения из предыдущих операций записи. После операций записи положение курсора не изменяется. Управляющие символы, такие, как возврат каретки и перевод строки, не действуют и записываются как обычные символы. В связи с этим после вывода символа следует, используя функцию 02h прерывания int 10h, переместить курсор на следующую позицию. Функция вывода символа имеет формат :

На входе: ah = 0ah - запись символа без атрибута;

al = ASCII - код записываемого символа;

bh = номер страницы видеопамяти;

bl = цвет (для графических режимов);

cx = число записываемых символов (повторений).

На выходе: Не используются.

Подробный анализ работы программы можно провести на основании листинга, приведенного ниже. Эта программа реализует алгоритм, описание которого было приведено при описании блок - схемы программы.

 

.Model small,C

.CODE

Public puts

puts proc near

ARG p_string:word

LOCAL max_string:word,max_stolb:word

;Определяем число строк и столбцов в развертке

mov ax,40h

mov es,ax

xor ah,ah

mov al,byte ptr es:[84h]

mov max_string,ax

mov ax,es:[4ah]

dec ax

mov max_stolb,ax

;Определяем текущую активную страницу экрана

push si

push bx

push dx

push cx

push di

xor di,di

mov si,p_string

mov ah,0fh

int 10h ;номер активной страницы в регистре bh

;Получаем в dx координаты курсора

mov ah,3

int 10h

;В цикле выводим на экран символы строки

nex_char:

lodsb

cmp al,0 ;находим конец строки

je exit_proc ;если конец достигнут,

;то оканчиваем процедуру

cmp al,’\’

jne m

inc di

jmp nex_char

m: cmp di,1

jne m1

xor di,di

cmp al,’n’

jne m1

;перемещение курсора на следующую строку

inc dh

cmp dh,byte ptr max_string

jle m2 ;следующая строка помещается на экране

push ax

push bx

mov ah,06h

mov al,1

mov bh,07h

xor cx,cx

mov dh,byte ptr max_string

mov dl,byte ptr max_stolb

int 10h

pop bx

pop ax

m2: mov ah,02h

xor dl,dl

int 10h

jmp nex_char

m1:

mov ah,0ah

mov cx,1 ;символы строки выводятся без повтора

int 10h

;Перемещаем курсор на следующую позицию

mov ah,2

inc dl

int 10h

jmp nex_char

exit_proc:

pop di

pop cx

pop dx

pop bx

pop si

ret

puts ENDP

END

Рис. 2.2. Листинг программы puts.

;Запись строки символов. Эта пограмма в файле put_str.asm

EXTRN _puts:near

.MODEL small,C

.DATA

message db '\nint 10h\n',0

massage1 db 'Пример применения функции puts\n',0

.STACK 100h

.CODE

beg proc far

push ds

sub ax,ax

push ax

mov ax,@data

mov ds,ax

 

;Отображаем на активной странице строку message.

;Такой вызов корректен при использования соглашения языка Си.

call _puts, offset message

 

;-----------------------------------------------------------

;Это другой вариант вызова функции _puts. При этом отображается ;содержимое строки message1.

mov ax, offset message1

push ax

call _puts

add sp,2

;-------------------------------------------------------------

ret

beg ENDP

END beg

Рис. 2.3. На этом рисунке представлена программа put_str, которая является вызывающей для puts.

Приведенные выше функции gets и puts позволяют создать простейший диалог между пользователем и компьютером. Однако, для того чтобы облегчить отладку программы ,желательно иметь процедуру подобную функции getc языка Си. Листинг такой функции приведен на рис. 2.4.

 

;getc.asm . Ввод с ожиданием с клавиатуры без эха.

; char getc();

;Код прочитанного символа возвращается в al

;-------------------------------------------------------------------

.MODEL small,C

 

.CODE

PUBLIC getc

getc proc near

mov ah,08h

int 21h

ret

getc ENDP

END

Рис. 2.4. Ввод символа с клавиатуры.

 

;Пример диалога с пользователем программа put_get6.asm.

 

puts MACRO tex_str

LOCAL @met

.DATA

@met db tex_str,0

.CODE

call _puts,offset @met

ENDM

 

getc MACRO

puts '\n'

call _getc

ENDM

 

put MACRO p_str

call _puts,offset p_str

ENDM

 

gets MACRO outstr

call _gets, offset outstr

ENDM

 

EXTRN _gets:near, _puts:near,_getc:near

 

L_STROKA=82

.MODEL small,C

 

.DATA

message db '\n Начинаем диалог!!\n',0

stroka db L_STROKA dup(?)

 

.STACK 1024

 

.CODE

beg proc far

push ds

sub ax,ax

push ax

mov ax,@data

mov ds,ax

;Отображаем на активной странице экрана строку message

b: puts '\n Введите строку\n'

gets stroka

puts '\n Печать введенной строки\n'

put stroka

getc

cmp al,'q'

je a

jmp b

a:

puts '\n Конец сеанса.'

getc

ret

beg ENDP

END beg

 

Рис. 2.5. Пример организации диалога. Программа put_get6.asm.

 

В программе представленной на рис. 2.5 для вызова подпрограмм широко используются макросы, которые определены в начале программы. Применение макросов позволяет значительно сократить описание вызовов необходимых процедур. Это особенно заметно, если все макросы включить в отдельный заголовочный файл. Этот файл обычно имеет расширение *.h. В случае использование макросов достаточно воспользоваться директивой include c именем заголовочного файла. По мере разработки новых макросов их можно включать в этот же заголовочный файл. Назовем наш заголовочный файл именем stud_lab.h. Включим в этот файл все наши макросы и дополнительно элементы, которые являются общими для многих приложений. На рис. 2.6 представлен заголовочный файл stud_lab.h. В дальнейшем этот файл мы будем расширять.

 

puts MACRO tex_str

LOCAL @met

.DATA

@met db tex_str,0

.CODE

call _puts,offset @met

ENDM

 

getc MACRO

puts '\n'

call _getc

ENDM

 

put MACRO p_str

call _puts,offset p_str

ENDM

 

gets MACRO outstr

call _gets, offset outstr

ENDM

 

EXTRN _gets:near, _puts:near,_getc:near

 

Рис. 2.6. Заголовочный файл stud_lab.h.

 

Теперь программа put_get6.asm будет выглядеть следующим образом:

 

include stud_lab.h

L_STROKA=82

.MODEL small,C

 

.DATA

message db '\n Начинаем диалог!!\n',0

stroka db L_STROKA dup(?)

 

.STACK 1024

 

.CODE

beg proc far

push ds

sub ax,ax

push ax

mov ax,@data

mov ds,ax

;Отображаем на активной странице экрана строку message

b: puts '\n Введите строку\n'

gets stroka

puts '\n Печать введенной строки\n'

put stroka

getc

cmp al,'q'

je a

jmp b

a:

puts '\n Конец сеанса.'

getc

ret

beg ENDP

END beg

 

Назовем эту программу put_get7.asm.

 

 





sdamzavas.net - 2020 год. Все права принадлежат их авторам! В случае нарушение авторского права, обращайтесь по форме обратной связи...