- •Таганрог 1997 Методическая разработка к лабораторным работам Программирование на языке ассемблера пэвм ibm pc
- •Введение
- •Структура описания лабораторной работы
- •Выполнение работы
- •Разработка и отладка программ на языке ассемблера
- •2.2. Обработка программ в dos
- •Трансляция программы
- •Компоновка программы
- •Запуск программы
- •2.3. Использование отладчика td
- •Как запустить программу под отладчиком
- •Что умеет и чего не умеет отладчик td
- •Меню View Окно Module
- •Окно cpu
- •Окно Watches
- •Окно Dump
- •Экран пользователя
- •Команда Instruction Trace
- •Команда Program Reset
- •3. Пример выполнения работы
- •4. Контрольные вопросы
- •2.2. Режимы адресации
- •3. Пример выполнения работы
- •4. Варианты заданий
- •5. Контрольные вопросы
- •Лабораторная работа
- •Циклические и разветвляющиеся программы1. Цель работы
- •2. Основные сведения
- •3. Пример выполнения работы
- •4. Варианты заданий
- •5. Контрольные вопросы
- •Лабораторная работа
- •Логические команды1. Цель работы
- •2. Основные сведения
- •2.1. Логические команды
- •2.2. Примеры использования логических команд
- •3. Пример выполнения работы
- •4. Варианты заданий
- •5. Контрольные вопросы
- •Лабораторная работа
- •Символьная обработка1. Цель работы
- •2. Основные сведения
- •2.1. Программные прерывания и системные вызовы
- •2.2. Функции dos для ввода с клавиатуры
- •2.3. Функции dos для вывода на экран
- •3. Пример выполнения работы
- •Inpstr db 80, ?, 82 dup( ? ) ; буфер ввода
- •Inc count[si] ;увеличиваем соответств. Счетчик
- •Xor si, si ;Счетчик цифр
- •Int 21h ; строки
- •Inc si ;Счетчик очередной цифры
- •4. Варианты заданий
- •5. Контрольные вопросы
- •Лабораторная работа
- •Десятичная арифметика
- •2.3. Команды десятичной коррекции неупакованных чисел
- •3. Пример выполнения работы
- •4. Варианты заданий
- •5. Контрольные вопросы
- •Лабораторная работа
- •Подпрограммы1. Цель работы
- •2. Основные сведения
- •2.1. Описание подпрограмм
- •2.2. Вызов подпрограмм
- •2.3. Передача параметров
- •2.4. Сохранение регистров
- •2.5. Локальные переменные
- •2.6. Директивы описания сегментов и модели памяти Модели памяти
- •Директивы определения сегментов
- •Макрокоманды начала и завершения программы
- •2.7. Расширенные директивы описания процедур
- •2.8. Область действия имен
- •2.9. Итоги
- •3. Пример выполнения работы
- •Int 21h ;Приглашение к вводу строки
- •Int 21h ;Ввод строки
- •Int 21h ; позиции удаления
- •Int 21h ;Ввод строки числа
- •Int 21h ; числа удаляемых
- •Int 21h ;Ввод строки числа удаляемых
- •Int 21h ;Заголовок вывода
- •Inc bx ;Сдвиг по строке
- •Int 21h ; Вывод результата
- •Inc bx ;Сдвиг по строке
- •4. Варианты заданий
- •5. Контрольные вопросы
- •Лабораторная работа 8 Использование подпрограмм на языке ассемблера в программах на языках c и pascal1. Цель работы
- •2. Основные сведения
- •2.1. Введение
- •2.2. ТерминЫ и сокращения
- •2.3. Соглашения о связях
- •Преобразование имен
- •Передача и возврат управления и данных
- •Сохранение регистров
- •Трансляция и компоновка
- •Преобразование данных
- •Трансляция и компоновка
- •3. Пример выполнения работы
- •3.1. Интерфейс Pascal
- •Inc si ;указатель на входную строку
- •Inc cx ;нет, увеличиваем счетчик символов
- •Inc dx ;да, увеличиваем счетчик строк
- •Inc dx ;нет, будем увеличивать счетчик строк
- •4. Варианты заданий
- •5. Контрольные вопросы
- •БиблиографИя
- •Содержание
- •Заметки
- •Дроздов Сергей Николаевич Калачев Дмитрий Петрович
2.4. Сохранение регистров
Каждая подпрограмма должна либо сохранять значения всех регистров процессора (кроме тех, которые используются для возврата результатов), либо, в крайнем случае, в описании подпрограммы должно быть четко указано, какие регистры она портит. Для сохранения регистров используется стек. Команды push служат для помещения регистров в стек, а pop – для их восстановления перед возвратом из подпрограммы. Сохранение регистров должно выполняться после загрузки BP (см. предыдущий параграф).
2.5. Локальные переменные
Переменные, размещенные в сегменте данных, являются статическими (аналогично переменным с классом static в Си). Конечно, их можно рассматривать как локальные переменные подпрограмм, обеспечив локализацию области действия с помощью директивы locals (см. ниже). Однако такое статическое распределение памяти под локальные переменные не соответствует понятию локальных переменных в блочных языках типа Pascal или C, поскольку время существования таких переменных – время существования программы. Для того чтобы решить данную проблему, т.е. обеспечить динамическое распределение памяти под локальные переменные, следует выделять для них память в стеке (как это делается в Pascal или C).
Предположим, что в подпрограмме должно быть две локальные переменные длиной в слово. Чтобы обеспечить выделение памяти, для них перед командами сохранения регистров следует добавить команду:
sub SP, 4
которая резервирует в стеке два слова.
После выполнения этой команды стек будет выглядеть следующим образом:
|
|
1-я лок.пер. |
SP |
2-я лок.пер. |
|
BP |
сохраненное значение BP |
IP |
адрес возврата |
2-й параметр |
параметр, занесенный в стек вторым |
1-й параметр |
параметр, занесенный в стек первым |
. . . |
|
И, если определить структуру:
__locvars struc
__var1 dw ?
__var2 dw ?
__locvars ends,
то доступ к локальным переменным можно осуществить с помощью команд:
mov AX, __var1[BP-4];загрузить в AX значение 1-й локальной переменной mov BX, __var2[BP-4];загрузить в BX значение 2-й локальной переменной
Чистка стека от локальных переменных должна выполняться после восстановления сохраненных регистров, это можно сделать с помощью команды:
add SP, 4
или
mov SP, BP
2.6. Директивы описания сегментов и модели памяти Модели памяти
Директива model позволяет вам задать для программы несколько стандартных моделей сегментации. Вы можете также использовать ее для задания языка для процедур программы. Она имеет следующий синтаксис:
model [модификатор_модели] модель_памяти[имя_сегмента_кода] [,[модификатор_языка] язык] [, модификатор_модели]
модель_памяти и модификатор_модели определяют модель сегментации памяти, используемую в программе.
В применяемых в Турбоассемблере стандартных моделях можно использовать специальные сегменты для: кода; инициализированных данных; неинициализированных данных; инициализированных данных дальнего типа; неинициализированных данных дальнего типа; констант; стека.
Сегмент кода содержит обычно код модуля (но при необходимости может также содержать данные). В целях совместимости с языками высокого уровня инициализированные данные и константы интерпретируются по-разному. Они содержат такие данные, как сообщения, когда важно начальное значение. Неинициализированные данные и стек содержат данные, начальные значения которых не существенны. Инициализированные данные дальнего типа (far) – это неинициализированные данные, которые не являются частью стандартного сегмента данных и которые доступны только при изменении значения сегментного регистра. Это же относится к неинициализированным данным дальнего типа.
Единственным обязательным параметром директивы model является модель памяти. Каждая стандартная модель памяти описывается в табл. 1.
Таблица 1
Модель |
Код |
Данные |
Предполагаемые регистры |
Описание |
TINY |
near |
near |
cs=dgroup ds=ss=dgroup |
Весь код и все данные комбинируются¦ в одну группу с¦ именем DGROUP. Эта¦ модель используется¦ для программ, ассемблируемых в формат .COM. Некоторые¦ языки эту модель не¦ поддерживают. |
SMALL |
near |
near |
cs=_text ds=ss=dgroup |
Код представляет собой один сегмент. Все данные комбинируются в группу с именем DGROUP. Это наиболее общая модель, использующаяся для автономных программ на ассемблере. |
MEDIUM |
far |
near |
cs=<модуль>_text ds=ss=dgroup |
Для кода используется несколько сегментов, по одному на модуль. Данные находятся в группе с именем DGROUP. |
COMPACT |
near |
far |
cs=_text ds=ss=dgroup |
Код находится в одном сегменте. Все ближние данные находятся в группе с именем DGROUP. Для ссылки на данные используются дальние указатели. |
Окончание табл. 1
Модель |
Код |
Данные |
Предполагаемые регистры |
Описание |
LARGE |
far |
far |
cs=<модуль>_text ds=ss=dgroup |
Для кода используется несколько сегментов, по одному на модуль. Все ближние данные находятся в группе с именем DGROUP. Для ссылки на данные используются дальние указатели. |
HUGE |
far |
far |
cs=<модуль>_text ds=ss=dgroup |
То же, что модель LARGE (что касается Турбоассемблера). |
FLAT |
near |
near |
cs=_text ds=ss=flat |
То же, что и модель SMALL, но подходит для использования в OS/2 и Win32. |
Поле модификатор_модели позволяет вам изменить отдельные аспекты модели. Вы можете задавать при необходимости несколько модификаторов модели. Доступные модификаторы модели приведены в табл. 2.
Таблица 2
Модификатор модели |
Функция |
NEARSTACK |
Указывает, что сегмент стека должен включаться в DGROUP (если группа DGROUP присутствует), а SS должен указывать на DGROUP. |
FARSTACK |
Указывает, что сегмент стека не должен включаться в DGROUP, а SS должен указывать не nothing (не определен). |
USE16 |
Задает, что все сегменты в выбранной модели должны быть 16-разрядными (при выборе процессора 80386 или старше). |
USE32 |
Задает, что все сегменты в выбранной модели должны быть 32- разрядными (при выборе процессора 80386 или старше). |
DOS, OS_DOS |
Задает, что прикладная программа ориентируется на DOS. |
OS2, OS_OS2 |
Задает, что прикладная программа ориентируется на OS2, Win32. |
Язык и модификатор_языка вместе определяют соглашения, используемые при вызове процедуры, а также используемый по умолчанию характер начала и завершения кода каждой процедуры. Они определяют так же, как будут объявляться общедоступные идентификаторы (которые использует компоновщик).