- •Архитектура пэвм
- •Пользовательские регистры
- •Регистры общего назначения
- •Сегментные регистры
- •Регистры состояния и управления
- •Регистры защищенного режима:
- •Организация памяти (реальный режим)
- •Элементы синтаксиса Ассемблера
- •Операторы
- •Директивы сегментации
- •Модели памяти
- •Идентификаторы, создаваемые директивой Model:
- •Этапы создания программы на ассемблере
- •2. Создание объектного модуля (трансляция программы)
- •3. Создание загрузочного модуля (компоновка программы)
- •4. Отладка программы
- •Определение простых типов данных:
- •Способы адресации Регистровая адресация
- •Непосредственная адресация
- •Способы адресации памяти
- •Переопределение сегмента
- •Особенности пересылки данных
- •Xch ax, bx ; команда двунаправленного обмена
- •Команды работы с адресами и указателями
- •Команды сдвига
- •Команды линейного сдвига
- •Команды циклического сдвига
- •Команды сдвига двойной точности
- •Примеры работы с битовыми полями
- •Команды преобразования данных
- •Xor ax, ax ; очистка регистра ax
- •Int 21h ;ожидание вода с клавиатуры
- •Команды обработки строк
- •Команды пересылки строк
- •Команды сравнения строк
- •Пример.
- •Сканирование строки
- •Загрузка элемента строки в аккумулятор
- •Перенос элемента из аккумулятора в строку
- •Ввод элемента цепочки из порта в строку
- •Вывод элемента цепочки в порт
- •Пример использования вложенных циклов
- •Массивы
- •Логические команды
- •Xor операнд1,операнд2
- •Логические команды поиска
- •Структуры
- •Описание шаблона структуры:
- •Заполнение шаблона:
- •Работа с полями структуры
- •Пример:
- •Шаблон записи:
- •Xor bl, mask i2 ; обнуление
- •Команды передачи управления
- •Безусловные переходы
- •Межсегментные переходы
- •Второй сегмент
- •Команды условного перехода
- •Команды условного перехода и флаги
- •Процедуры
- •Процедура в начале кодового сегмента
- •Процедура в конце кодового сегмента
- •Процедура в теле сегмента
- •Вызов процедуры
- •Ret [число]
- •Способы вызова процедуры
- •Прямой ближний вызов
- •Прямой дальний вызов
- •Косвенный ближний вызов
- •Косвенный дальний вызов процедуры
- •Организация интерфейса между процедурами, расположенными в разных модулях
- •Передачи параметров в процедуру через регистры
- •Фрагмент модуля 2
- •Возврат результата из процедуры
- •Макрокоманды и макроопределения
- •Особенности трансляции при получении объектного модуля
- •Где можно разместить макроопределение?
- •Связь Assembler с языками высокого уровня
- •Операторы типа inline
- •Ассемблерные вставки
- •Внешние процедуры Операторы типа inline
- •Ассемблерные вставки
- •Требования к программе на языке Assembler
- •Требования к программе на языке Pascal
- •Передача параметров из Pascal-программы в программу на ассемблере
- •Использование директивы model для организации взаимодействия программ
- •Int 10h; вывод символа
- •Возврат данных в вызывающую программу
- •Пример взаимодействия программ
- •Особенности com-программы
- •Пример программы типа .Com
- •Резидентные программы
- •Формат резидентной программы
- •Собственно программу.
- •Функцию записи в оп адреса точки входа программы для последующего вызова.
- •Функцию, которая оставляет программу резидентной.
- •Пример резидентной программы типа .Com
- •Iret ;возврат из процедуры
- •Int 27h ; оставляем программу резидентной
- •Вызов резидентной программы
- •Запись адреса резидентной программы в область межзадачных связей
- •Iret ;возврат из процедуры
- •Int 27h ; оставляем программу резидентной
- •Вызов резидентной программы через область межзадачных связей
- •Передача параметров в резидентную программу
- •Замена существующего вектора прерывания
- •Динамическое распределение памяти
- •Пример выделения и освобождения блока памяти
- •Int 21h ;блока памяти
- •Дочерние процессы
- •Особенности структуры материнской программы
- •Активизация дочернего процесса
- •Пример материнской программы
- •; Запуск дочернего процесса
- •Int 21h ; запуск дочернего процесса
- •Int 21h ; выход в ос (завершение программы)
- •Получение и анализ кода возврата в материнской программе
- •Int 21h ; код возврата передается через регистр al
- •Передача кода возврата из дочерней программы
- •Прерывания
- •Программируемый контроллер прерываний
- •Прохождение запроса на прерывание через контроллер
- •Программирование контроллера прерываний
- •Формат приказов icw
- •Формат приказов ocw
- •И f спользование таймера в программах на Assembler
- •Формирование задержки
- •Использование прерываний 8h для управления запуском программ
- •Программирование коммуникационного порта (com)
- •Микросхема uart 8250
- •Инициализация порта
- •Пример программы инициализации порта
- •Регистр статуса линии (порта)
- •Работа порта без использования механизма прерываний
- •Получение данных
- •Передача данных
- •Алгоритм работы программы приема /передачи без прерываний
- •Текст программы
- •Работа com – порта в режиме прерываний
- •Регистр разрешения прерываний
- •Регистр идентификации прерывания
- •Вызов обработчика прерывания
- •Управление модемом через порт
- •Пример установления связи через порт и модем
- •Защищенный режим микропроцессора
- •2. Регистры отладки
- •3. Регистры управления Регистры системных адресов
- •Структура дескрипторных таблиц
- •Локальная дескрипторная таблица (ldt)
- •Структура дескриптора:
- •Структура байта ar
- •Обработка прерываний в защищенном режиме
- •Особенности обработки ловушек
- •Шлюз задачи
- •Дескриптор tss
- •Структура шлюза вызова
2. Создание объектного модуля (трансляция программы)
На этом шаге формируется объектный модуль, который включает в себя представление исходной программы в машинных кодах и некоторую другую информацию, необходимую для отладки и компоновки его с другими модулями.
Для получения объектного модуля исходный файл программы на ассемблере, который должен быть предварительно подготовлен и записан на диск, необходимо подвергнуть трансляции при помощи программы tasm.exe из пакета TASM. Формат командной строки для запуска tasm.exe следующий:
TASM [опции] имя_исходного_файла [,имя_объектного_файла] [,имя_файла_листинга] [,имя_файла_перекрестных_ссылок]
Если вы забыли формат командной строки и возможные значения параметров, то получить быструю справку на экране монитора можно запустив файл tasm.exe без задания каких-либо аргументов. Обратите внимание, что большинство параметров заключено в квадратные скобки. Это общепринятое соглашение по обозначению параметров, которые могут отсутствовать.
Таким образом, обязательным аргументом командной строки является имя_исходного_файла. Этот файл должен находиться на диске и обязательно иметь расширение .asm. За именем исходного файла через запятую могут следовать необязательные аргументы, обозначающие имена объектного файла, файла листинга и файла перекрестных ссылок.
Если имена объектного файла , файла листинга и файла перекрестных ссылок должны совпадать с именем исходного файла (наиболее типичный случай), то нужно просто поставить запятые вместо имен этих файлов:
TASM /zi prog,,,
Применение опции /zi разрешает транслятору сохранить связь символических имен в программе и их смещений в системе кода, что позволит отладчику производить отладку, используя оригинальные имена. В результате будут созданы файлы, как показано на рис. 1 для шага 2.
Если имена объектного файла, файла листинга и файла перекрестных ссылок не должны совпадать с именем исходного файла, то нужно в соответствующем порядке в командной строке указать имена соответствующих файлов, к примеру:
TASM /zi prog,,proglist,
В результате на диске будут созданы файлы:
-
prog.obj
-
proglist.lst
-
prog.xrf
-
Если требуется выборочное создание файлов, то вместо ненужных файлов необходимо подставить параметр nul. например:
TASM /zi prog,,nul,
В результате на диске будут созданы файлы:
prog.obj
prog.crf
Логика работы программы для транслятора не имеет никакого значения. Вы можете написать абсолютную чушь, но если она будет синтаксически правильна, транслятор поспешит вас обрадовать, сообщив, что всё хорошо. Наличие строки Warning означает, что конструкция синтаксически правильна, но не соответствует некоторым соглашениям языка и это может послужить источником последующих ошибок.
Следует знать, что при наличии синтаксических ошибок в программе, объектный файл не будет создан, а на экране появится сообщение об ошибках.
Для устранения ошибок нужно определить место их возникновения и проанализировать ситуацию. Место ошибки легко определяется по значению в скобках в сообщении об ошибке. Это значение является номером ошибочной строки. Запомнив его, вы переходите в файл с исходной программой и по номеру строки находите место ошибки.
Этот способ локализации ошибок имеет недостатки. Во-первых, он не нагляден. Во- вторых, не всегда номер строк сообщений соответствует действительным номерам ошибочных строк в исходном файле. Такая ситуация будет наблюдаться, например, в том случае, если вы используете макрокоманды. При их использовании транслятор вставляет файл дополнительные строки в соответствии с описанием применяемой макрокоманды, в результате чего получается отличие в нумерации.
Для локализации ошибок лучше использовать информацию из специального, создаваемого транслятором файла листинга. Этот файл имеет расширение .lst; его имя определяется в соответствии с теми соглашениями, которые мы разобрали выше.
Ниже приведен полный формат листинга для программы, содержащей некоторые ошибки. Листинг- очень важный документ, и ему нужно уделить должное внимание.
Turbo Assembler Version 3.1 13/09/09 15:10:55 Page 1
Prog.asm
1 ;Программа преобразования двузначного шестнадцатеричного числа
2 ;из символьного представления в двоичное
3 ;Результат преобразования будет в регистре bl
4 ;Вводить цифры или прописные буквы: A,B,C,D,E,F !!!
5
6 0000 data segment para public 'data' ;Определяем сегмент данных
7 0000 82 A2 A5 A4 A8 E2 A5+ mes1 db 'Введите первую цифру $'
8 20 AF A5 E0 A2 E3 EE+
9 20 E6 A8 E4 E0 E3 20+
10 20 24
11 0017 82 A2 A5 A4 A8 E2 A5+ mes2 db 'Введите вторую цифру $'
12 20 A2 E2 AE E0 E3 EE+
13 20 E6 A8 E4 E0 E3 20+
14 20 24
15 002E data ends
16
17 0000 stk segment stack 'stack' ; Определяем сегмент стека
18 0000 0100*(3F) db 256 dup('?')
19 0100 stk ends
20
21 0000 code segment 'code' ;Начало сегмента кода
22 0000 main proc
23 assume cs:code, ds:data, ss:stk
24 0000 B8 0000s mov ax,data
25 0003 8E D8 mov ds,ax
26 0005 B4 09 mov ah,9h ;Выводим на экран
27 0007 BA 0000r mov dx,offset mes1 ;строку
28 000A CD 21 int 21h ; mes1
29 000C 33 C0 xor ax,ax ;Очистим регистры ax
30 000E 33 DB xor bx,bx ; и bx
31 0010 B4 01 mov ah,1h ;Ввод с клавиатуры
32 0012 CD 21 int 21h ;первой цифры (загружается в регистр al)
33
34 0014 2C 30 sub al,30h ;Вычитаем из al число 30h
35 0016 3C 09 cmp al,9h ;Сравниваем результат с 9h
36 0018 7E 02 jle m1 ;Если меньше или равно, то на метку m1
37 001A 2C 07 sub al,7h ;Иначе - вычитаем из al число 7h
38 001C m1:
39 001C 02 1E 0000 add bl,a1 ; Загружаем в bl первое число
**Error** Prog.asm(33) Undefined symbol: A1
40 0020 D1 E3 D1 E3 D1 E3 D1+ shl bx,4h ;Сдвигаем содержимое bx на 4
; разряда влево
41 E3
42
43 0028 B4 09 mov ah,9h ; Выводим на экран
44 002A BA 0017r mov dx,offset mes2 ; строку
45 002D CD 21 int 21h ; mes2
46
47 002F B4 01 mov ah,1h ;Ввод с клавиатуры
48 0031 CD 21 int 21h ;второй цифры
49
50 0033 2C 00 sub al,300h ;Повторение
**Error** Prog.asm(43) Constant too large
51 0035 3C 09 cmp al,9h ;проверки
52 0037 7E C7 jle m2 ;кода
**Error** Prog.asm(45) Undefined symbol: M2
53 0039 2C 07 sub al,7h ;ASCII
54 003B m22:
55 003B 02 D8 add bl,al ;Загружаем в bl второе число
56
57 003D B8 4C00 mov ax, 4c00h ;Выход
58 0040 CD 21 int 21h ; в систему
59 0042 main endp
60 0042 code ends ;Окончание сегмента кода
61 end main
Symbol Name Type Value Cref (defined at #)
??DATE Text "13/09/09"
??FILENAME Text "Prog "
??TIME Text "15:10:55"
??VERSION Number 030A
@CPU Text 0101H
@CURSEG Text CODE #6 #17 #21
@FILENAME Text PROG
@WORDSIZE Text 2 #6 #17 #21
M1 Near CODE:001C 36 #38
M22 Near CODE:003B #54
MAIN Near CODE:0000 #22 61
MES1 Byte DATA:0000 #7 27
MES2 Byte DATA:0017 #11 44
Groups & Segments Bit Size Align Combine Class Cref (defined at #)
CODE 16 0042 Para none CODE #21 23
DATA 16 002E Para Public DATA #6 23 24
STK 16 0100 Para Stack STACK #17 23
**Error** Prog.asm(33) Undefined symbol: A1
**Error** Prog.asm(43) Constant too large
**Error** Prog.asm(45) Undefined symbol: M2
Файл листинга содержит, в частности, код ассемблера исходной программы. Но в листинге приводится расширенная информация об этом коде. Для каждой команды ассемблера указываются её машинный (объектный) код и смещение в кодовом сегменте.
Кроме того, в конце листинга TASM формирует таблицы, которые содержат информацию о метках и сегментах, используемых в программе, а также информацию о размерах и других параметрах сегментов кода, данных и стека.
Если есть ошибки или сомнительные участки кода, то TASM включает в конец листинга сообщение о них. Если сравнивать их с сообщениями TASM, выводимыми на экран, то видно, что они совпадают. Кроме того, что очень удобно, эти же сообщения включаются в текст листинга после ошибочной строки.
Строки в файле листинга имеют следующий формат:
<глубина_вложенности> <номер_строки> <смещение> <машинный_код> <исходный код>
Здесь:
-
<глубина_вложенности> - уровень вложенности включаемых файлов или макрокоманд в файле;
-
<номер_строки> - номер строки в файле листинга. Этим номера используются для локализации ошибок и форматирования таблицы перекрестных ссылок. Помните, что эти номера могут не соответствовать номерам строк в исходном файле.
В добавлении к вышесказанному нужно отметить, что ассемблер имеет директиву INCLUDE, которая позволяет включить в данный файл строки другого файла. Нумерация при этом как и в случае макрокоманд, будет последовательная для строк обоих файлов. Факт вложенности кода одного файла в другой фиксируется увеличением значения <глубина_вложенности> на единицу. Это замечание касается и использования макрокоманд;
-
<смещение> - смещение в байтах текущей команды относительно начала сегмента кода. Это смещение называют также счетчиком адреса. Смещение вычисляет транслятор для адресации в сегменте кода;
-
<машинный_код> - машинное представление команд ассемблера,
-
<исходный_код> - строка кода из исходного файла.
Дальнейшие действия зависят от характера ошибки.
Исправлять ошибки следует в исходном файле с расширением asm. Исправив несколько первых ошибок (если они есть), перетранслируйте программу и приступайте к устранению следующих ошибок. Возможно, что это делать не придётся, так как после исправления одной ошибки могут исчезнуть и последующие (так называемые наведенные ошибки).
О нормальном окончании процесса трансляции можно судить по сообщению TASM, в котором отсутствуют строки с сообщениями об ошибках и предупреждениях.
Изучая внимательно файл листинга, вы, наверное, заметили, что не все строки исходной программы имеют соответствующий <машинный_код>. Это обстоятельство обусловлено тем, что исходный файл на ассемблере в общем случае может содержать конструкции следующих типов:
-
команды ассемблера — конструкции, которым соответствуют машинные команды;
-
директивы ассемблера — конструкции, которые не генерируют машинных команд, а являются указаниями транслятору на выполнение некоторых действий или служат для задания режима его работы;
-
макрокоманды — конструкции, которые, будучи представлены одной строкой в исходном файле программы, после обработки транслятором генерируют в объектном модуле последовательность команд, директив или макрокоманд ассемблера.
Формат листинга и его полнота не являются жестко регламентированными. Их можно изменить, задавая в исходном файле программы директивы управления листингом.