- •Лабораторная работа №1 Начало работы на языке ассемблера
- •Просмотр работы программы в Турбоотладчике (Td.Exe);
- •Задания
- •Int 21h
- •Int 21h
- •7. Напишите в отчете основные отличия в создании
- •Команды пересылки данных. Стек.
- •Задание
- •Арифметические операции. Битовые команды.
- •Задание
- •X dw ?
- •Int 21h
- •4. Наберите приведенную программу 2, запишите исходный файл с расширением *.Asm, получите файл с расширением *.Exe.
- •Int 21h
Лабораторная работа №1 Начало работы на языке ассемблера
Цель работы:
ознакомление с общими принципами построения программ на языке ассемблера;
обучение работе с программами Tasm.exe, Tlink.exe;
создание *.EXE файла первой программы
Просмотр работы программы в Турбоотладчике (Td.Exe);
ознакомление со структурой программы на ассемблере;
дать понятие о директивах определения данных;
директивы DATA, CODE, Mode;
Задания
Создайте файл с именем Lab2.asm.
.Model Small ;Модель памяти ближнего типа
.Stack 100h ;Определяет стек размером 100h
.Data ;Начало сегмента данных
Hello DB 'Лабораторная работа №2 !$' ;Зарезервировали память
;для переменной HELLO
.Code ;Начало сегмента кода
Start:
mov ax,@DATA ;Формирование адреса сегмента
mov ds,ax ;данных
lea DX,Hello ;Установить в DX адрес переменной HELLO
mov ah,09h ;Функция DOS вывода строки
int 21h ;Вывод строки на экран
mov ax,4C00h ;Функция DOS завершения
int 21h ;программы
END start ;конец программы
2. Создайте исполняемый файл Lab2.EXE, выполнив ассемблирование и компоновку файла.
3. Пример создания программы в виде *.com файла
3.1. Войдите в директорию TASM, в ней создайте файл с именем Lab21.asm. Введите текст следующей программы (без комментариев).
; Пример оформления программы в виде com-файла
.MODEL SMALL
.CODE
org 100h
begin:
jmp start
Hello DB 'Hello!$'
start: LEA DX,Hello
mov ah,09h
Int 21h
mov ah,4ch
mov al,00h
Int 21h
END begin
3.2 Создайте исполняемый *.com файл Lab2.com, выполнив ассемблирование и компоновку файла Lab2.asm. При компоновки наберите TLINK/t Lab2
4. Напишите отчет о директивах ассемблера
5. Продемонстрируйте работающие программы Lab1.exe, Lab2.com
6. Показать работа двух программ в Турбоотладчике
7. Напишите в отчете основные отличия в создании
Пункт 4.
ДИРЕКТИВЫ АССЕМБЛЕРА
Ассемблер имеет ряд операторов, которые позволяют упpавлять процессом
ассемблирования и формирования листинга. Эти операторы называются
псевдокомандами или директивами. Они действуют только в процессе
ассемблирования программы и не генерируют машинных кодов.
Директивы управления листингом: PAGE и TITLE
----------------------------------------------
Ассемблер содержит ряд директив, управляющих форматом печати (или
листинга). Обе директивы PAGE и TITLE можно использовать в любой
программе.
Д и р е к т и в а PAGE. В начале программы можно указать количество
строк, распечатываемых на одной странице, и максимальное количество
символов на одной строке. Для этой цели cлужит директива PAGE. Следующей
директивой устанавливается 60 строк на страницу и 132 символа в строке:
PAGE 60,132
Количество строк на странице может быть в пределах от 10 до 255, а
символов в строке - от 60 до 132. По умолчанию в ассемблере установлено
PAGE 66,80.
Предположим, что счетчик строк установлен на 60. В этом случае
ассемблер, распечатав 60 строк, выполняет прогон листа на начало следующей
страницы и увеличивает номер страницы на eдиницу. Кроме того можно
заставить ассемблер сделать прогон листа на конкретной строке, например, в
конце сегмента. Для этого необходимо записать директиву PAGE без
операндов. Ассемблер автоматически делает прогон листа при обработке
диpективы PAGE.
Д и р е к т и в а TITLE. Для того, чтобы вверху каждой страницы
листинга печатался заголовок (титул) программы, используется диpектива
TITLE в следующем формате:
TITLE текст
Рекомендуется в качестве текста использовать имя программы, под
которым она находится в каталоге на диске. Например, если программа
называется ASMSORT, то можно использовать это имя и описательный
комментарий общей длиной до 60 символов:
TITLE ASMSORT - Ассемблерная программа сортировки имен
В ассемблере также имеется директива подзаголовка SUBTTL, которая
может оказаться полезной для очень больших программ, содержащих много
подпрограмм.
Директива SEGMENT
-------------------
Любые ассемблерные программы содержат по крайней мере один сегмент -
сегмент кода. В некоторых программах используется сегмент для стековой
памяти и сегмент данных для определения данных. Асcемблерная директива для
описания сегмента SEGMENT имеет следующий формат:
Имя Директива Операнд
имя SEGMENT [параметры]
.
.
.
имя ENDS
Имя сегмента должно обязательно присутствовать, быть уникальным и
соответствовать соглашениям для имен в ассемблере. Директива ENDS
обозначает конец сегмента. Обе директивы SEGMENT и ENDS должны иметь
одинаковые имена. Директива SEGMENT может содержать три типа параметров,
определяющих выравнивание, объединение и класс.
1. В ы р а в н и в а н и е. Данный параметр определяет границу
начала сегмента. Обычным значением является PARA, по которому сегмент
устанавливается на границу параграфа. В этом случае начальный адрес
делится на 16 без остатка, т.е. имеет шест. адрес nnn0. В случае
отсутствия этого операнда ассемблер принимает по умолчанию PARA.
2. О б ъ е д и н е н и е. Этот элемент определяет объединяется
ли данный сегмент с другими сегментами в процессе компоновки после
ассемблирования (пояснения см. в следующем разделе "Компоновка
программы"). Возможны следующие типы объединений: STACK, COMMON,
PUBLIC, AT выражение и MEMORY. Сегмент стека определяется следующим
образом:
имя SEGMENT PARA STACK
Когда отдельно ассемблированные программы должны объединяться
компоновщиком, то можно использовать типы: PUBLIC, COMMON и MEMORY. В
случае, если программа не должна объединяться с другими программами,
то данная опция может быть опущена.
3. К л а с с. Данный элемент, заключенный в апострофы,
используется для группирования относительных сегментов при
компоновке:
имя SEGMENT PARA STACK 'Stack'
Фрагмент программы на рис.3.1. в следующем разделе иллюстрирует
директиву SEGMENT и ее различные опции.
Директива PROC
----------------
Сегмент кода содержит выполняемые команды программы. Кроме того этот
сегмент также включает в себя одну или несколько процедур, определенных
директивой PROC. Сегмент, содержащий только одну процедуру имеет следующий
вид:
имя-сегмента SEGMENT PARA
имя-процедуры PROC FAR Сегмент
. кода
. с
. одной
RET процедурой
имя-процедуры ENDP
имя-сегмента ENDS
Имя процедуры должно обязательно присутствовать, быть уникальным и
удовлетворять соглашениям по именам в ассемблере. Операнд FAR указывает
загрузчику DOS, что начало данной процедуры является точкой входа для
выполнения программы.
Директива ENDP определяет конец процедуры и имеет имя, аналогичное
имени в директиве PROC. Команда RET завершает выполнение программы и в
данном случае возвращает управление в DOS.
Сегмент может содержать несколько процедур (см. гл.7).
Директива ASSUME
------------------
Процессор использует регистр SS для адресации стека, регистр DS для
адресации сегмента данных и регистр CS для адресации cегмента кода.
Ассемблеру необходимо сообщить назначение каждого сегмента. Для этой цели
служит директива ASSUME, кодируемая в сегменте кода следующим образом:
Директива Операнд
ASSUME SS:имя_стека,DS:имя_с_данных,CS:имя_с_кода
Например, SS:имя_стека указывает, что ассемблер должен ассоциировать
имя сегмента стека с регистром SS. Операнды могут записываться в любой
последовательности. Регистр ES также может присутствовать в числе
операндов. Если программа не использует регистр ES, то его можно опустить
или указать ES:NOTHING.
Директива END
---------------
Как уже показано, директива ENDS завершает сегмент, а директива ENDP
завершает процедуру. Директива END в свою очередь полностью завершает всю
программу:
Директива Операнд
END [имя_процедуры]
Операнд может быть опущен, если программа не предназначена для
выполнения, например, если ассемблируются только определения данных, или
эта программа должна быть скомпонована с другим (главным) модулем. Для
обычной программы с одним модулем oперанд содержит имя, указанное в
директиве PROC, которое было oбозначено как FAR.
Директивы описания данных: [имя] dn выражение
где: n=bилиwилиd(соответственно для байтов, слов, двойных слов). имя элемента данных не обязательно,но если в программе имеются ссылки (обращения) на некоторый элемент, то это делается посредством имени. Имена данных могут включать латинские буквы, цифры (не в качестве первого знака имени) и некоторые специальные знаки, например, знаки подчеркивания (_), доллара ($) и коммерческого at (@). Длину имени некоторые ассемблеры ограничивают (например, ассемблер MASM - 31 символом), другие - нет, но в любом случае слишком длинные имена затрудняют чтение программы. С другой стороны, имена данных следует выбирать таким образом, чтобы они отражали назначение конкретного данного, например counter для счетчика или filename для имени файла: counter dw 10000 filename db 'a:\myfile.001' Для определения данных используются, главным образом, три директивы ассемблера:db(define byte, определить байт) для записи байтов,dw(define word, определить слово) для записи слов иdd(define double, определить двойное слово) для записи двойных слов.
Пункт 6.
6. Показать работа двух программ в Турбоотладчике
Скриншот работы программы Lab2.exeвtd.exe
Адрес сегмента данных DS= 087Ah, далее идет загрузка регистраDXсмещением данных по адресу 2hв сегменте данных и вывод на экран прерываниемint21h(вывод строки,ah=9),
затем загружается код завершения al=0 и код функции «выйти в ДОС» (ah=4ch) и выполняется выход в ДОС с помощью прерыванияint21h.
Скриншот работы программы Lab2.comвtd.exe
Происходит jmp в обход данных на адрес CS:10Ah, затем dx загружается адресом данных и производится вывод на экран функцией ah=9 прерывания int 21h, далее программа завершается с кодом = 0 при помощи функции ah=4ch прерывания
int 21h.