Emu8086 Запускаем программу Emu8086 и создаём новый файл через меню file new com template (Файл Новый Шаблон файла com). В редакторе исходного кода после этого мы увидим следующее Рис. Создание нового файла в Emu8086
Скачать 251.21 Kb.
|
ПеременныеПеременные хранятся в памяти по определенным адресам. Программисту проще иметь дело именами переменных, чем с адресами в памяти. Например, переменная с именем "var1" будет более понятна в коде программы, чем адрес 5A73:235B, особенно когда количество переменных велико. Наш компилятор поддерживает два типа переменных: BYTE иWORD.
Как вы уже знаете из части 2 этих уроков, команда MOVиспользуется для копирования значения из источника в приемник. Давайте посмотрим другой пример с командой MOV:
Скопируйте вышеприведенный код в редактор кода Emu8086 и нажмите клавишу F5, чтобы откомпилировать и загрузить этот код в эмулятор. Вы увидите примерно такую картину: На рисунке вы можете заметить команды, похожие на те, что используются в нашем примере. Только переменные заменены фактическими местоположениями в памяти. Когда компилятор создает машинный код, он автоматически заменяет имена всех переменных их смещениями. По умолчанию сегмент загружен в регистр DS (в COM-файлах значение регистра DS устанавливается таким же, что и значение в регистре CS - сегменте кода). В таблице памяти (memory) первый столбец - это смещение, второй столбец - это шестнадцатиричное значение, третий столбец -десятичное значение, а последний столбец - это символ ASCII, соответствующий данному числу. Компилятор не чувствителен к регистру, поэтому "VAR1" и "var1" - это одно и то же. Смещение переменной VAR1 - это 0108h, а полный адрес -0B56:0108. Смещение переменной var2 - это 0109h, а полный адрес -0B56:0109. Эта переменная имеет тип WORD, поэтому занимает 2 БАЙТА. Принято младший байт записывать по меньшему адресу, поэтому 34h размещается перед 12h. Вы можете увидеть некоторые другие инструкции после командыRET. Это случается потому, что дизассемблер не знает, где начинаются данные. Он только обрабатывает значения в памяти и понимает их как имеющие силу инструкции процессора 8086 (мы изучим их позже). Вы можете даже написать программу, используя только директивуDB:
Скопируйте вышеприведенный код в редактор кода Emu8086 и нажмите клавишу F5, чтобы откомпилировать и загрузить этот код в эмулятор. Вы получите тот же самый дизассемблированный код и тот же самый результат работы программы! Как вы можете догадаться, компилятор только преобразует исходный код программы в набор байтов. Этот набор байтов называетсямашинным кодом. Процессор обрабатывает машинный код и выполняет его. ORG 100h - это директива компилятора (она указывает компилятору как обрабатывать исходный код). Эта директива очень важна при работе с переменными. Она указывает компилятору, какой исполняемый файл будет загружаться в смещение (offset) 100h (256 байтов), так что компилятор должен вычислить правильный адрес для всех переменных, когда он размещает имена переменных с их смещениями. Директивы никогда не преобразуются в какой-либо реальный машинный код. Почему исполняемый файл загружается по смещению 100h? Операционная система хранит некоторые данные о программе в первых 256 байтах, начиная от CS(сегмента кода), такие как параметры командной строки и т.д. Все это справедливо только для COM-файлов, файлы EXE загружаются по смещению 0000, и обычно используют специальный сегмент для переменных. Может быть, мы поговорим об EXE-файлах позже. Получение адреса переменной Есть такая команда LEA (Load Effective Address) и альтернативный оператор OFFSET. Как OFFSET так и LEA могут быть использованы для получения смещения адреса переменной. LEA более мощная, т.к. она также позволяет вам получить адрес индексированных переменных. Получение адреса переменной может быть очень полезно в различных ситуациях, например, если вам необходимо поместить параметр в процедуру. Напоминание: Чтобы указать компилятору тип данных, вы должны использовать следующие префиксы: BYTE PTR - для байта. WORD PTR - для слова (два байта). Например: BYTE PTR [BX] ; доступ к байту. или WORD PTR [BX] ; доступ к слову. Emu8086 поддерживает короткие префиксы: b. - для BYTE PTR w. - для WORD PTR иногда компилятор может вычислить тип данных автоматически, но вы не можете и не должны полагаться на это, если один из операндов является непосредственным значением. Здесь первый пример:
Здесь другой пример, который использует OFFSET вместо LEA:
Оба примера функционально идентичны. Эти строки: LEA BX, VAR1 MOV BX, OFFSET VAR1 даже компилируются в одинаковый машинный код: MOV BX, num num - это 16-битовое значение смещения переменной. Пожалуйста учтите, что только эти регистры могут использоваться внутри квадратных скобок (как указатели памяти): BX, SI, DI, BP! (См. предыдущую часть уроков). Константы Константы подобны переменным, но они существуют до того, как ваша программа откомпилирована (ассемблирована). После определения константы ее значение не может быть изменено. Для определения константы используется директива EQU: имя EQU < любое выражение > Например:
Этот пример функционально идентичен коду:
Вы можете наблюдать переменные во время выполнения программы, если выберите пункт "Variables" в меню "View" эмулятора. Чтобы наблюдать массивы, вы должны щелкнуть по переменной и установить свойство Elements - размер массива. В Ассемблере нет строгих типов данных, поэтому любые переменные могут быть представлены как массив. Переменная может быть просмотрена в любой числовой системе:
Вы можете редактировать переменные, когда ваша программа выполняется, просто щелкнув дважды по переменной или выбрать ее и щелкнуть кнопку Edit. Можно вводить числа в любой системе, шестнадцатиричные цифры должны иметь суффикс "h", двоичные - суффикс "b", восмеричные - суффикс "o", десятичные цифры не требуют суффикса. Строка может быть введена следующим способом: 'hello world', 0 (эта строка заканчивается нулем). Массив может быть введен следующим способом: 1, 2, 3, 4, 5 (массив может быть массивом байтов или слов, это зависит от того, выбран ли BYTE или WORD для введенной переменной). Выражения преобразуются автоматически, например: если введено это выражение: 5 + 2 оно будет преобразовано в 7 и т.п... |