|
Emu8086 Запускаем программу Emu8086 и создаём новый файл через меню file new com template (Файл Новый Шаблон файла com). В редакторе исходного кода после этого мы увидим следующее Рис. Создание нового файла в Emu8086
Библиотека общих функций - emu8086.inc Чтобы облегчить программирование, имеются несколько общих функций, которые можно включать в вашу программу. Чтобы использовать в вашей программе функции, определенные в другом файле, вы должны применить директиву INCLUDE, за которой следует имя файла. Компилятор автоматически найдет файл в той же папке, где размещен файл с исходным кодом программы, а если там этого файла не окажется, то поиск будет продолжен в папке Inc.
Возможно, что на сегодняшний момент вы не сможете полностью понять содержимое emu8086.inc (расположенной в каталоге Inc), но это не страшно, т.к. вам достаточно понять, для чего все это нужно.
Чтобы использовать какие-либо функции в emu8086.inc, вы должны вписать следующую строку в вашем исходном файле:
include 'emu8086.inc'
emu8086.inc определяет следующие макросы:
PUTC char - макрос с одним параметром, печатает ASCII-символ в текущей позиции курсора.
GOTOXY col, row - макрос с двумя параметрами, устанавливает позицию курсора.
PRINT string - макрос с одним параметром, печатает строку.
PRINTN string - макрос с одним параметром, печатает строку. Это тоже самое, что и PRINT, но автоматически добавляется "перевод каретки" в конце строки (аналогично процедуре Writeln в Паскале).
CURSOROFF - скрывает текстовый курсор.
CURSORON - показывает текстовый курсор.
Чтобы использовать какой-либо из вышеописанных макросов, просто напечатайте его имя в нужном месте вашего кода и, если необходимо, параметры. Например:
include emu8086.inc ORG 100h PRINT 'Hello World!' GOTOXY 10, 5 PUTC 65 ; 65 - это ASCII-код для буквы 'A'
PUTC 'B' RET ; вернуться в операционную систему.
END ; директива для окончания компиляции.
|
Когда компилятор обрабатывает ваш исходный код, он ищет файлemu8086.inc для объявленных макросов и заменяет имя макроса реальным кодом. Вообще макросы - это относительно небольшие участки кода, частое использование макросов может сделать вашу программу (исполнимый файл) слишком большой (для оптимизации размера лучше использовать процедуры).
emu8086.inc также определяет следующие процедуры:
PRINT_STRING - процедура для печати строки с нулевым окончанием с текущей позиции курсора. Получает адрес строки в регистре DS:SI. Чтобы использовать эту процедуру, следует объявить: DEFINE_PRINT_STRING перед директивой END.
PTHIS - процедура для печати строки с нулевым окончанием с текущей позиции курсора (как и PRINT_STRING), но получает адрес из стека. Строка с нулевым окончанием должна быть определена только после команды CALL. Например:
CALL PTHIS db 'Hello World!', 0
Чтобы использовать эту процедуру, следует объявить:DEFINE_PTHIS перед директивой END.
GET_STRING - процедура для получения строки с нулевым окончанием от пользователя. Принятая строка записана в буфер, адрес которого указан в DS:DI, размер буфера должен быть в DX. Процедура завершает ввод, если нажата клавиша 'Enter'. Чтобы использовать эту процедуру, следует объявить:DEFINE_GET_STRING перед директивой END.
CLEAR_SCREEN - процедура для очистки экрана (выполняет полную прокрутку экрана и устанавливает курсор в его верхней части) Чтобы использовать эту процедуру, следует объявить:DEFINE_CLEAR_SCREEN перед директивой END.
SCAN_NUM - процедура, которая получает многозначное число СО ЗНАКОМ с клавиатуры, и записывает результат в регистр CX. Чтобы использовать эту процедуру, следует объявить:DEFINE_SCAN_NUM перед директивой END.
PRINT_NUM - процедура, которая печатает число со знаком, которое находится в регистре AX. Чтобы использовать эту процедуру, следует объявить: DEFINE_PRINT_NUM перед директивой END.
PRINT_NUM_UNS - процедура, которая печатает число без знака из регистра AX. Чтобы использовать эту процедуру, следует объявить: DEFINE_PRINT_NUM_UNS перед директивой END.
Чтобы использовать какую-либо из вышеописанных процедур, вы должны сначала объявить функцию в нижней части вашего файла (но перед END!!), а затем использовать команду CALL, за которой следует имя процедуры. Пример:
include 'emu8086.inc' ORG 100h LEA SI, msg1 ; попросить ввести число
CALL print_string ;
CALL scan_num ; получить число в CX. MOV AX, CX ; копировать число в AX. ; напечатать следующие строки:
CALL pthis
DB 13, 10, 'You have entered: ', 0 CALL print_num ; напечатать число из AX. RET ; вернуться в операционную систему. msg1 DB 'Enter the number: ', 0 DEFINE_SCAN_NUM
DEFINE_PRINT_STRING
DEFINE_PRINT_NUM
DEFINE_PRINT_NUM_UNS ; требуется для print_num.
DEFINE_PTHIS END ; директива окончания компиляции.
|
Сначала компилятор обрабатывает объявления (это просто обычные макросы, которые рассматриваются до процедур). Когда компилятор получает команду CALL, он заменяет имя процедуры адресом кода, где объявлена процедура. Когда выполнится команда CALL, то управление будет передано процедуре. Это очень удобно: даже если вы вызовите в вашем коде одну и ту же процедуру 100 раз, то вы все-равно будете иметь относительно небольшой размер исполнимого файла. Кажется сложным, не так ли? Но это не страшно. Со временем вы все это изучите, а пока достаточно понимания только основных принципов.
|
|
|