Регистр bp можно использовать так же, как использовался bx, только адресуемые данные должны находиться в стеке.
4.38. Комментарии
Один из способов включения в код ассемблера комментариев состоит в том, чтобы справа от каждой инструкции помещать комментарий, в котором содержится ее краткое пояснение. Например:
mov [bx],al ; сохранить измененный символ
Не обязательно комментировать каждую строку. Например: mov ah,1
int 21h ; получить следующую клавишу
Целью комментариев является не объяснение каждого элемента программы, а облегчение анализа ее текста и понимания.
Другим хорошим методом является использование для пояснения блоков кода строк-комментариев. Такие комментарии могут описывать работу программы на более высоком уровне, чем комментарии отдельных строк. Например:
; Сгенерировать для буфера передачи байт контрольной суммы
mov |
bx,offset TransferBuffer |
|
mov cx,transfer_buffer_length |
||
sub |
al,al |
; очистить аккумулятор контрольной суммы |
CheckSum: |
|
|
add |
al,[bx] |
; добавить в него текущее значение байта |
inc |
bx |
; указать на следующий байт |
В комментарии к этому блоку кратко суммируется его работа, поэтому тот, кто будет просматривать программу, больше полезного извлечет из комментариев к блокам, чем из комментариев к строкам.
Третий метод состоит во включении перед каждой подпрограммой описательного заголовка-комментария ("шапки" программы). Такой заголовок может содержать описание подпрограммы, ее входные и выходные значения и различные замечания по ее работе. Например:
;Функция, возвращающая контрольную сумму (один байт) буфера данных
;Входные данные ds: bx – указатель на начало буфера
;cx – длина буфера
;Выходные данные: al – контрольная сумма буфера
;Используемые регистры (содержимое не сохраняется): bx, cx
;Примечание: буфер не должен превышать 64 Кб
; |
и не должен пересекать границу сегментов. |
CheckSum proc near |
|
sub |
al,al ; очистить аккумулятор контрольной суммы |
|
46 |
add al,[bx]; прибавить текущее значение байта inc bx ; ссылка на следующее значение loop CheckSum
ret CheckSum endp
Если подпрограмма написана и отлажена, то редко приходится снова просматривать ее текст. Все, что требуется знать, – это какие функции выполняет подпрограмма и как подпрограмма взаимодействует с вызывающей ее программой. Этим целям хорошо отвечает описательный заголовок.
4.39. Набор инструкций процессоров семейства iAPx86
Набор инструкций включает в себя все действия, которые программист может заставить выполнить процессор. Перечень используемых в первой лабораторной работе инструкций (команд) ассемблера приведен в табл.3.2, а полный набор имеется в [6, с.134-138]. Эти инструкции выполняют множество действий – от пустой операции, которая не выполняет никаких функций (nop), до копирования 65 535 слов
(rep movsw).
4.40. Системное программное обеспечение для семейства IBM PC
СПО используется в качестве промежуточного уровня между прикладными программами и аппаратным обеспечением компьютера.
Например, чтобы обработать одно нажатие клавиши, требуется несколько сотен строк на ассемблере, однако ваша программа может получить символ (код) клавиши с помощью только одной системной функции.
Ваша программа всегда имеет возможность управлять аппаратными средствами непосредственно, но лучше по возможности пользоваться функциями DOS и базовой системы ввода-вывода BIOS.
4.41.Операционная система DOS
Воперационной системе (ОС) предусмотрено также большое число функций, которые широко используются любой прикладной задачей. С помощью функций DOS прикладные задачи выполняют чтение из файлов и запись в них данных, получают символы клавиш или устанавливают и получают текущее время. Например, фрагмент программы на ассемблере:
mov ah,2; функция DOS вывода символа
mov |
dl,'A' ; A – это символ, который нужно вывести на экран |
int |
21h |
вызывает функцию DOS вывода на экран, чтобы вывести символ A в текущей позиции курсора.
47
Функции DOS следует вызывать для ввода с клавиатуры или из файла, вывода на экран или в файл и на печать.
DOS часто скрывает различия между компьютерами. Таким образом, если Вы игнорируете функции DOS и выходите непосредственно на аппаратуру, ваши программы могут не работать на других машинах и, кроме того, может оказаться, что программы, работающие в обход DOS, не смогут сосуществовать с другими программами. К тому же зачем писать лишний код, если функция DOS может выполнить то, что вам нужно.
Рассмотрим функции DOS, используемые в лабораторной работе №1.
4.42. Получение символов с клавиатуры
Ввод информации с клавиатуры – один из основных способов взаимодействия с компьютером IBM PC. Одним из наиболее простых способов получения символов клавиш является функция "Ввод с клавиатуры", то есть функция DOS номер 1. Функции DOS вызываются путем помещения номера функции в регистр ah и выполнения затем инструкции int 21h. Набранный на клавиатуре символ возвращается в регистре al. Например, когда выполняется код
mov |
ah,1 |
; ah:=1 (функция ввода одного символа с клавиатуры) |
int |
21h |
|
DOS помещает следующий набранный на клавиатуре символ в регистр al. Если клавиша не нажата, DOS будет ждать, когда она будет нажата, поэтому для выполнения данной функции может потребоваться неопределенное время.
4.43. Вывод символов на экран
Функция DOS с номером 2 обеспечивает наиболее непосредственный путь вывода символа на экран. Для этого нужно просто поместить 2 в регистр ah и выводимый символ в регистр dl, а затем вызвать DOS с помощью int 21h. Следующий код отображает каждый введенный символ на экране:
mov |
ah,1 |
; ah:=1 (функция ввода одного символа с клавиатуры) |
int |
21h |
; т.е. получить код следующей нажатой клавиши (в al) |
mov |
dl,al |
; скопировать считанный символ из al в dl (dl:=al) |
mov |
ah,2 |
|
int |
21h |
; вывести его на экран. |
4.44. Вывод сообщения на экран в базовой версии DOS
Вывод на экран в базовой версии DOS требует определения текстового сообщения в области данных, установки в регистре ah значения 09 (вызов функциии DOS) и указания команды DOS int 21h. В процессе
48
выполнения операции конец сообщения определяется по oграничителю ($), как это показано ниже:
;сегмент данных
msg db 'Имя покупателя?','$'
;сегмент кода
mov ah,09h ;запрос вывода на экран lea dx, msg ;загрузка адреса сообщения int 21h ;вызов DOS
Знак ограничителя $ можно кодировать:
–непосредственно после cимвольной строки (показано выше);
–внутри строки: 'Имя покупателя?$';
–или в следующем операторе db '$'.
Используя данную операцию, нельзя вывести на экран символ доллара $. Кроме того, если знак доллара будет отсутствовать в конце строки, то на экран будут выводиться все последующие символы, пока знак $ не встретится в памяти.
Команда lea загружает адрес области msg в регистр dx для передачи в DOS адреса выводимой информации. Этот адрес является oтносительным, поэтому для вычисления абсолютного адреса данных DOS «складывает» (см. п.4.18) значения регистров ds и dx (ds:dx).
4.45. Ввод данных с клавиатуры в базовой версии DOS
Для ввода, использующего базовую DOS, область ввода требует наличия cписка параметров, содержащего поля, необходимые при
выполнении команды int. |
Пример. |
|
vvod_b |
label byte |
; Список параметров: |
maxlen_b db 4 |
; максимальная длина |
|
fact_b |
db 0 |
; реальная длина |
simv_b |
db "0000" |
; введенные символы |
Первый байт содержит максимальную длину вводимых данных. Это необходимо для предупреждения пользователя звуковым сигналом, если набран слишком длинный текст; символы, превышающие максимальную длину, не принимаются. Максимальное значение поля – 999#. Символ # использован здесь для индикации конца данных, так как шестнадцатеричный код клавиши Enter (0dh) не имеет отображаемого символа
Второй байт необходим DOS для занесения в него действительного числа введенных символов.
Третьим байтом начинается поле, которое будет содержать введенные символы.
49
Так как директива label не занимает места, то vvod_b и maxlen указывают на один и тот же aдрес памяти. Атрибут byte – один из возможных атрибутов этой директивы (см. п.4.56.)
Для запроса на ввод необходимо поместить в регистр ah номер функции – 10 (шестнадцатеричное 0ah), загрузить адрес списка параметров (vvod_b в нашем примере) в регистр dx и выполнить int 21h:
mov ah,0ah ;запрос функции ввода
lea dx, vvod_b |
;загрузить адреса списка параметров |
int 21h |
;вызвать DOS |
Команда int ожидает, пока пользователь не введет с клавиатуры текст, проверяя при этом, чтобы число введенных cимволов не превышало максимального значения, указанного в списке параметров (4 в нашем примере). Для указания конца ввода пользователь нажимает клавишу Enter. Код этой клавиши (шестнадцатеричное 0d) также заносится в поле ввода (у нас – simv_b).
Пример. Пусть требуется вводить список имен, длина которых не превышает десяти символов. Тогда список параметров для ввода может
иметь вид: |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Datasg segment para ‘Data’ |
|
|
|
|
|
|
|
|
|
|
|
||||
|
spisok |
label byte |
|
;Список параметров |
|
|
|
|
|
|
|
|||||
|
maxlen |
db 11 |
|
|
; максимальная длина |
|
|
|
|
|
|
|||||
|
fact db 0 |
|
|
; реальная длина |
|
|
|
|
|
|
|
|
||||
|
simv_sp db "00000000000"; введенные символы |
|
|
|
|
|
|
|||||||||
|
Допустим, пользователь ввел имя BROWN и нажал клавишу Enter. |
|||||||||||||||
Список параметров в этом случае будет содержать информацию: |
|
|
|
|||||||||||||
|
Значение |
|
spisok |
|
simv_sp |
+1 |
+2 |
+3 |
+4 |
+5 |
+6 |
|
|
|
|
|
|
Десятичное |
11 |
6 |
В |
R |
O |
W |
N |
# |
0 |
0 |
0 |
0 |
0 |
|
|
|
Шестнадцатеричное |
0B |
06 |
42 |
52 |
4F |
57 |
4E |
0d |
30 |
30 |
30 |
30 |
30 |
|
|
Во второй байт списка параметров (fact в нашем примере) команда заносит длину введенного имени – 6. Код Enter находится по адресу simv_sp+5. Т.к. максимальная длина в 11 символов включает шестнадцатеричное 0d, то можно ввести текст не более 10 символов. Подробнее о функциях DOS в [1, с.131 – 192].
В DOS не предусмотрен форматный ввод и вывод. DOS выполняет только посимвольный или построчный ввод-вывод.
Ваша программа на ассемблере должна явно преобразовывать переменные в строки символов, перед тем как вывести их на экран, и преобразовывать вводимые строки и символы в двоичный вид.
Программа, которая выполняет просто эхоотображение на экране строки набранных на клавиатуре символов, приведена ниже. Для завершения программы имеется несколько функций DOS, но наиболее
50