Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Met_Lab2_121113

.pdf
Скачиваний:
16
Добавлен:
11.05.2015
Размер:
1.72 Mб
Скачать

Завершать работу с отладчиком следует командой File = Quit или с помощью клавиш <Alt+X>. TD имеет множество других возможностей, изучить которые вам предлагается самостоятельно.

Лабораторная работа №1

Тема работы. Введение в изучение языка программирования Assembler.

Цель работы. Начальное ознакомление с базовыми приемами программирования на языке Ассемблер.

Содержание работы.

Для написания программы на ассемблере подходит любой текстовый редактор, который сохраняет текст в файле в кодировке ASCII, при этом не оставляя скрытых символов форматирования. Есть множество таких редакторов, специализированных для набора исходных кодов программ и имеющих функции цветового выделения кода и др. В рамках данного пособия используется редактор файлового менеджера FAR (аналогичны NC, VC, DN и др.).

Напишем простийшую программу, которая выводит сообщение на экран:

1IDEAL

2MODEL small

3

STACK

256

 

4

DATASEG

 

5

Message

DB

'Hello, World $'

6

CODESEG

 

7

Start:

mov

ax,@data

8

 

mov

ds,ax

9

 

mov

ah,09h

10

 

mov

dx,offset Message

11

 

int

21h

12

Exit:

mov

ax,4C00h

13

 

int

21h

14

END

Start

Подробный разбор данной программы приведен в разделе 4.

Запустите любой подходящий текстовый редактор и наберите текст предложенной программы, используя при этом символы табуляции для разделения различных элементов кода (директив, команд процессора и операндов) по колонкам для лучшей читаемости. Сохраните файл с текстом программы в файле Hello.asm.

После того как файл Hello.asm сохранен, исходный модуль готов. Необходимо произвести компиляцию программы. Сначала произведем трансляцию кода в объектный модуль, для этого наберите в командной строке:

tasm Hello.asm

Как уже упоминалось в разделе 2.1., для того, что бы можно было запустить транслятор tasm из любого текущего каталога, не переходя для этого в каталог, где он находится, необходимо в файле Autoexec.bat (который находится в корневом каталоге диска, на котором установлена ОС Windows) записать директиву PATH с указанием пути к каталогу с транслятором. Однако текущий каталог из которого происходит трансляция должен содержать файл исходного модуля Hello.asm.

В случае, если у Вас нет прав на изменение содержимого файла Autoexec.bat, необходимо будет либо производить трансляцию, поместив файл с исходным текстом программы и транслятор в одну папку, либо указывать в команде полные адреса к обоим

51

файлам (к файлу транслятору tasm.EXE и файлу с исходным кодом программы Hello.ASM), например:

C:/TASM/Bin/tasm.exe C:/My_Programs/Hello.asm

После того, как пройдет компиляция, убедитесь, что программа не содержала ошибок. Если ошибок в программе не было, то в сообщении транслятора строка ошибок будет иметь вид:

Error messages: None

Если же в программе была допущена хотя бы одна ошибка, то сообщение транслятора будет содержать отчет о найденной ошибке (рис. Л1).

Рис. Л1. Сообщение транслятора

Все строки, начинающиеся с **Error**, содержат описание синтаксических ошибок в программе. В данных строках указывается имя файла, в котором найдена ошибка, в круглых скобках указывается номер строки, в которой допущена ошибка и в конце описание этой ошибки.

На рис. Л1. продемонстрирована ошибка в файла Hello.ASM в строке № 7, которая заключается в том, что компилятор не смог найти экземпляр (константу, переменную, строку, метку и т.д.) DATA.

Строки, начинающиеся с *Warning*, содержат аналогичные описание предупреждений. Предупреждение от ошибки отличается тем, что при наличии ошибок программа не может быть компилирована, но при наличии предпреждений может. Однако не стоит игнорировать предупреждения и своевременно пытаться внести исправления в программу для их устранения.

В случае удачной трансляции в каталоге, в котором находится файл исходного модуля Hello.ASM должен появится файл объектного модуля Hello.OBJ.

Вторым шагом компиляции программы является компановка объектного модуля. Компановка осуществляется аналогично трансляции, но с помощью компановщика tlink.EXE. Аналогично выполните запуск компановщика tlink.EXE, указав в качестве параметра объектный модуль:

tlink Hello.obj

Для того, чтобы использовать дополнительны ключи компилятора или компановщика, при их вызове нужно указать ключи с помощью символа "/". Например:

tasm /c Hello.asm

Примечание. Указывать расширения *.asm для транслятора и *.obj для компановщика не обязательно.

Задания к работе.

1.Произведите компиляцию файла Hello.ASM с использованием ключа zi для транслятора и ключа v для компановщика.

2.Запустите на отладку скомпилированный исполняемый модуль в отладчике Td.EXE.

52

3. Операторы и директивы

3.1. "Препроцессорные" директивы I CLUDE и EQU

Директивы INCLUDE и EQU аналогичны директивам препроцессорной обработки #include и #define языка С. В отличие от большинства директив и команд Ассемблера эти две директивы могут стоять где угодно в программе, в том числе вне всех программных сегментов.

Формат директивы INCLUDE: include Имя_файла

Операнд Имя_Файла записывается по правилам операционной системы (и может включать в себя имя диска и имена каталогов).

Директива действует следующим образом. В то место, где стоит директива, вписывается указанный файл (если, конечно, он доступен). Фактически на компиляцию поступает текст программы со включенным файлом.

При помощи директивы INCLUDE можно оформить "скелет" простой программы на Ассемблере так, что не будет необходимости вмешиваться в него и вписывать что-либо вручную:

1

 

IDEAL

2

MODEL

small

3

STACK

256

4DATASEG

5Include my_data.asm

6CODESEG

7

Start: mov

ax,@data

8

 

mov

ds,ax

9

Include my_code.asm

10

Exit:

mov

ax,4C00h

11

 

int

21h

12

END

Start

 

Теперь необходимо только в текущем каталоге подготовить файл определения данных конкретной программы my_data.asm, и файл кодов конкретной программы my_codes.asm и запустить компилятор.

Директива EQU также может стоять в любом месте программы, в том числе вне любого программного сегмента. Ее формат:

Имя equ Операнд

Все три попя директивы являются обязательными. Смысл директивы состоит в том, что во всем тексте программы ниже директивы любое вхождение имени заменяется на значение операнда. Если в качестве операнда в правой части написано также некоторое имя, то имя, указанное в левой части, становится его псевдонимом, т.е. появляются два имени-синонима, которые можно использовать ниже по программе в равной степени для обозначения одного и того же обьекта.

Если в качестве операнда в правой части написано некоторое константное выражение, то оно вычисляется и ниже по программе каждое вхождение имени из левой части заменяется на это вычисленное значение.

53

Если в качестве операнда в правой части написана числовая константа, то директива является просто определением именованной константы (на практике чаще всего используется именно этот случай, например, для задания числа элементов массива). Значение именованной константы, заданной директивой EQU, не может быть изменено при помощи другой директивы EQU.

Если в качества операнда в правой части написан некий текст, который нельзя отнести ни к чему перечисленному выше, имя в правой части будет просто сокращенным обозначением текста.

Примеры:

counter equ CX N equ 2*К-1

maxbyte equ OFFh

noflle equ "File not found"

3.2. Директивы описания и инициализации переменных DB, DW и DD

3.2.1.Директива DB (Define Byte - определить байт)

Впростейшем варианте директива DB имеет формат:

Имя db Нач_Значение

Операнд Нач_Значение может быть в общем случае выражением, а в частном случае именем другой переменной (определенной ранее), константой, символом и знаком "?".

По этой директиве компилятор выделяет 1 байт памяти и закрепляет за ним указанное имя. Практически компилятор вводит псевдоним адреса выделенного байта, удобный для программиста. Кроме того компилятор хранит информацию о том, что любой двоичный код, который будет находиться по этому адресу, будет представлять собой 1-байтовую переменную.

Далее компилятор вычисляет выражение, стоящее в правой части и его значением инициализирует описанную переменную. Если вместо операнда стоит знак "?", то инициализация не производится и значение переменной непредсказуемо.

Примеры:

р db 1 ; р=1 q db 2 ; q=2

r db ? ; r не инициализировано s db 3+2 ; s=5

t db 'Ю' ; В байте t находится ASCII-код буквы Ю

Массив определяется либо как директива DB с несколькими операндами, либо как несколько директив db с именем только у первой директивы. В следующих двух примерах определяется один и тот же массив А с тремя элементами:

A db 7, ?, 'r' A db 7

db ? db 'r'

54

Строка символов также рассматривается как массив из символов, но для нее имеется укороченная форма записи инициализации. В следующих двух примерах определяется одна и та же строка S с начальным значением "Наука умеет много гитик":

S DB 'H', 'а', 'ука ', 'умеет ', 'много ', 'гитик' S DB 'Наука умеет много гитик'

Примечание. Любая строка перед выводом на экран должна «заканчиваться»,

для компилятора строка заканчивается сразу перед символом $.

3.2.2. Директивы DW и DD (Define Word и Define Double Word)

Директивы DW и DD действуют практически так же, как директива DB (естественно, с учетом того, что определяют не байт, а слово или двойное слово). Соответственно расширяются диапазоны целых чисел, которые могут быть использованы для инициализации.

Не следует забывать, что байтовые части слов и двойных слов записываются в памяти в "перевернутом" виде (младшие байты по младшим адресам), поэтому не следует применять эти директивы для определения строк (символы в строках будут "перетасованы").

Инициализатором директивы DW может быть имя переменной, определенной ранее (или, в более общем случае, адресное выражение). Например:

A db 7 ; В байте А число 00000111b В dw A ; В слова В смещение байта А

Использовать в директиве DD в качества инициализатора константное выражение не имеет смысла, поскольку любая из операций в константном выражении выполняется по модулю 2^16. Инициализатором директивы DD может быть имя переменной, определенной ранее (или, в более общем случае, адресное выражение). Например:

A db 7 : В байте А число 00000111b

С dd A ; В младшем слове С смещение байта А, в старшем слове С сегмент байта А Конструкция повторения и определение массивов в директивах DW и DD

применяются точно так же, как и в директиве DB.

3.3. Операторы Assembler

Любой алгоритмический язык программирования, в том числе и ассемблер, имеет операторы следующих типов:

Исполнительные операторы. Данные операторы преобразуются транслятором в машинные инструкции. Один исполнительный оператор ассемблера преобразуется в одну машинную инструкцию. А один исполнительный оператор языка высокого уровня транслируется в несколько машинных инструкций. Все исполнительные операторы языка программирования делятся на операторы обработки данных и операторы передачи управления. Операторы обработки данных влияют на содержимое ячеек памяти (ячейки ОП, регистры, флаги), а операторы передачи управления изменяют ход выполнения программы.

Псевдооператоры определения данных. В отличие от исполнительного оператора псевдооператор ни в какие машинные инструкции не транслируется, а представляет собой указание транслятору со стороны программиста. Псевдооператор определения данных

55

требует от транслятора выделить область памяти заданной длины. Кроме того, он может попросить транслятор поместить в выделенную область какие-то первоначальные данные. Впоследствии на этапе выполнения сама программа может менять содержимое этой области.

Другие псевдооператоры. Они информируют транслятор о структуре программы, помогая транслятору и редактору связей правильно преобразовать исполнительные операторы в машинные инструкции.

Макрооператоры. Каждый такой оператор заменяется транслятором на несколько обычных операторов языка программирования (в том числе, возможно, и псевдооператоров).

Комментарии. Это любые сообщения в исходной программе, предворяемые специальным символом. В рассматриваемом языке ассемблера это символ ";". Комментарии игнорируются транслятором и никак не влияют на текст машинной программы.

3.3.1. Операторы обработки данных

Операторы обработки данных делятся на:

1.арифметические операторы;

2.логические операторы;

3.операторы передачи данных;

4.операторы манипуляций флажками;

5.операторы сдвигов;

6.цепочечные (строковые) операторы.

Арифметические операторы

Они делятся на двоичные и двоично-кодированные десятичные инструкции. Второй из этих классов используется редко, т.к. применяемый в нем способ кодирования данных неэффективен по затратам памяти. В свою очередь, двоичные арифметические инструкции разделяются на знаковые и беззнаковые. Первые из них выполняют операции как над положительными так и над отрицательными двоичными числами, в то время как беззнаковые инструкции имеют дело только с положительными числами. Рассмотрим основные типы операторов ассемблера, выполняющие операции над двоичными числами.

Операторы сложения:

1)ADD (сложить) суммирует два операнда (слова или байты). Результат записывается на место первого операнда.

Примеры:

ADD АХ, Mem ; (АХ) + (Mem) -> АХ , Mem - слово в ОП ADD Mem, АХ ; (Mem) + (АХ) -> Mem

ADD AL,40 ;(AL) + 40 -> AL

ADD Mem, OFh ; (Mem) + OFh -> Mem

Запрещается суммировать содержимое двух ячеек ОП, а также записывать в качестве первого операнда непосредственное значение;

2)ADC (сложить с переносом) суммирует два операнда (слова или байты), а также флаг переноса CF. Результат помещается на место первого операнда.

Совместное применение инструкций ADD и ADC позволяет выполнить суммирование двух чисел даже тогда, когда результат не вмещается в 16 битов.

3)IKC ( инкремент) увеличивает операнд на 1. Пример: INC АХ ; (АХ) + 1 ->АХ

56

Операторы вычитания:

1)SUB (вычесть) выполняет вычитание второго операнда из первого операнда (операнды - байты или слова). Результат помещается в качестве первого операнда.

Примеры:

SUB АХ, СХ ; (АХ) - (СХ) -> АХ SUB АХ, Mem ; (АХ) - (Mem) -> АХ SUB Mem, АХ ; (Mem) - (АХ) -> Mem SUB AL, 10 ; (AL) - 10 -> AL

Запрещается брать в качестве обоих операндов ячейки ОП, а также задавать в качестве первого операнда непосредственное значение;

2)DEC (декремент) уменьшает операнд на 1.

Пример:

DEC AX ; (АХ)-1->АХ

3)KEG (изменить знак) вычитает из нулевого значения значение операнда. Результат записывается на место операнда.

Пример:

NEG АХ ; -(АХ) -> АХ

4) СМР (сравнить два операнда) выполняет вычитание 1-го и 2-го операндов, но в отличие от оператора SUB результат вычитания никуда не записывается, а лишь используется для установки флажков.

Примеры:

СМР АХ,ВХ ; (АХ)-(ВХ) CMP Mem,АН ; (Mem)-(АН) СМР AL, 10 ; (AL) -10

Операторы умножения:

1) MUL (умножить) выполняет умножение двух беззнаковых чисел (слов или байтов). Единственный операнд содержит один из сомножителей и представляет собой регистр общего назначения или ячейку памяти размером в байт или слово. В качестве второго сомножителя используется содержимое регистра AL (в операциях над байтами) или регистра АХ (в операциях над словами). 16-битовое произведение байтов помещается в регистры АН (старший байт) и AL (младший байт). 32-битовое произведение слов помещается в регистры DX (старшее слово) и АХ (младшее слово).

Примеры:

MUL ВХ ; Умножить ВХ на АХ без знака

MUL Mem_wor ; Умножить содержимое ячейки на АХ без знака MUL DL ; Умножить DL на AL без знака

2) IMUL (умножить целые числа) выполняет умножение двух знаковых чисел (слов или байтов). Правило размещения сомножителей и результата аналогично оператору MUL.

Операторы деления:

1) DIV (разделить) выполняет деление чисел без знака. Единственный операнд представляет собой регистр общего назначения или ячейку памяти (байт или слово) и содержит делитель. Делимое должно иметь двойной размер; оно извлекается из регистров АН и AL (при делении на байт) или из регистров DX и АХ (при делении на слово).

57

Результат возвращается следующим образом. Если делитель представляет собой байт, то частное возвращается в регистре AL, а остаток в регистре АН. Если делитель представляет собой слово, то частное возвращается в регистре АХ, а остаток в регистре DX.

Примеры:

DIV ВХ ; Разделить DX:AX на ВХ , без знака

DIV Membyte ; Разделить AH:AL на байт ОП, без знака

2) IDIV (разделить целые числа) выполняет деление чисел со знаком. Правило записи делимого, делителя и результата аналогично DIV.

Логические операторы

Они используются для установки и сброса битов в слове или в байте. В качестве операндов могут выступать два регистра, регистр с ячейкой ОП или непосредственное значение с регистром или ячейкой ОП.

1)AKD (логическое И) сравнивает два операнда (слова или байты) побитно. Результат записывается на место первого операнда. Если оба из сравниваемых битов равны 1, то результат равен 1, во всех остальных случаях результат равен 0. Например, пусть (AL) = 10101111, а (ВН) =11100000, тогда AND AL,BH запишет в AL 10100000.

Примеры:

AND AX, ВХ ; Операция AND над двумя регистрами

ANDAX, Memwor ; Операция AND над регистром и словом ОП AND Membyte, AL ; Операция AND над байтом ОП и регистром AND BL, 11110000b ; Обнуление младших 4-х битов регистра BL ANDMembyte, 00001111b ; Обну-е старших 4-х битов байта ОП

2)OR (логическое ИЛИ) сравнивает два операнда (слова или байты) побитно. Если хотя бы один из сравниваемых битов равен 1, то результат равен 1, если оба сравниваемых бита равны 0, то результат равен 0. Например, пусть (AL) =10101111, а (ВН) = 11100000, тогда OR AL, ВХ запишет в AL 11101111.

Примеры:

OR BL, 11110000b ; Установка в 1 старших 4-х и сохранение значений 4-х младших битов регистра BL

OR Mem byte, 00001111b ; Сохранение значений 4-х старших и установка в 1 4-х младших битов байта ОП

3)XOR (исключающее ИЛИ) сравнивает два операнда (слова или байты) побитно. Если один из сравниваемых битов равен 0, а другой 1, то результат есть 1, если оба сравниваемых бита одинаковы (оба - 0 или оба - 1), то результат есть 0.

4)TEST (проверить) выполняет логическое побитовое умножение своих двух операндов (байтов или слов), но в отличие от AND результат никуда не записывается, а лишь используется для установки флажков. Оба операнда остаются без изменения.

Пример:

TEST BL, 11110000b

установит флаг нуля в 1 только тогда, когда ни один из четырех старших битов в BL не равен 1.

5)KOT (НЕ) инвертирует все биты в операнде: вместо 0 пишет 1, а вместо 1-0.

Пример:

58

NOT AH ;К примеру AH был равен 010010011, в таком случае результатом будет 101101100

Операторы передачи данных

Они осуществляют обмен данными между регистрами и ячейками памяти.

1)MOV (переслать) пересылает содержимое второго операнда (слово или байт) в качестве содержимого первого операнда. Можно пересылать байт или слово между регистром и ячейкой памяти или между двумя регистрами. А также можно помещать непосредственное значение в регистр или в ячейку памяти.

Примеры:

MOV AX, Table ; Пересылка из ячейки ОП в регистр. MOV Table, AX ; и наоборот

MOV BL, AL ; Пересылка между регистрами MOV CL, -30 ; Загрузка константы в регистр MOV Mem, 25h ; или в ячейку ОП

Следует отметить, что с помощью данного оператора нельзя выполнять пересылку данных из одной ячейки ОП в другую ячейку ОП. Такая пересылка может быть осуществлена двумя операторами MOV с использованием регистра общего назначения.

С помощью оператора MOV можно загружать в регистр общего назначения (но не в регистр сегмента) номер начального параграфа сегмента, задав в качестве второго операнда имя сегмента.

Например:

MOV AX, Dataseg ; Data seg - имя сегмента данных

Для загрузки в регистр сегмента (кроме CS) номера начального параграфа сегмента требуются два оператора MOV. Например:

MOV AX, Dataseg ; Загрузка в АХ MOV DS, АХ ; Пересылка в регистр DS

Что касается регистра сегмента кода CS, то он не может быть использован в качестве первого операнда в операторе MOV. Кроме того, нельзя пересылать содержимое одного регистра сегмента в другой. Такая пересылка может быть осуществлена двумя операторами MOV с использованием регистра общего назначения.

2)XCHG (обменять) производит обмен содеряашого двух регистров или регистра и ячейки ОП. Следующие два фрагмента программ делают одно и то же - меняют местами содержимое двух байтов в ОП - Opr1 и Орг2:

а)

MOV AL, Opr1 ; (Oprl)-»AL MOV BL,Opr2 ; (Opr2)-4>BL MOV Opr2, AL ; (AL) -> Opr2 MOV Oprl,BL ; (BL)->Oprl б)

MOV AL,Oprl; (Oprl)-> AL XCHG AL;Opr2 ; (Opr2)->AL MOV Oprl,AL; (AL) -> Oprl

59

В варианте "б" потребовалось на одну инструкцию и на один регистр меньше, чем в

"а".

3)PUSH (поместить слово в стек) помещает содержимое регистра или ячейки ОП размером в 16-битовое слово на вершину стека.

Примеры:

PUSH АХ ; (АХ) -> стек PUSH Mem ; (Мem) -> стек

4)POP (извлечь слово из стека) выбирает слово из вершины стека и помещает его в ячейку памяти или в регистр.

Пример:

POP АХ ; Слово из вершины стека -> АХ

5)LEA (загрузить адрес) пересылает адрес (смещение) ячейки памяти в любой 16битовый регистр данных, регистр-указатель или индексный регистр. Оператор имеет два операнда. В качестве первого из них записывается регистр, а в качестве второго - метка ячейки ОП.

Пример:

LEA ВХ, Mem ; Смещение ячейки Mem -> ВХ

Операторы манипуляции флагами

Большинство операторов не только выполняют действия над своими операндами, но и выполняют действия над флажками - битами регистра флагов FLAGS.

Рис. 2.1. Структура регистра флагов

Семь битов в FLAGS не используются. Остальные биты (флаги) делятся на условные и управляющие.

Условные флаги

Отражают результат предыдущей арифметической или логической операции. Это:

1.SF - флаг знака. Равен старшему биту результата. Т.к. в дополнительном коде старший бит отрицательных чисел содержит 1, а у положительных он равен 0, то SF показывает знак предыдущего результата;

2.ZF - флаг нуля. Устанавливается в 1 при получении вулевого результата и сбрасывается в 0, если результат не равен 0;

3.PF - флаг паритета. Устанавливается в 1, если младшие 8 битов результата содержат четное число единиц: в противном случае он сбрасывается в 0;

4.CF - флаг переноса. При сложении (вычитании) устанавливается в 1, если возникает перенос (заем) из старшего бита (в старший бит);

5.AF - флаг вспомогательного переноса. Устанавливается в 1, если при сложении (вычитании) возникает перенос (заем) из бита 3. Флаг предназначен только для двоично-десятичной арифметики;

6.OF - флаг переполнения. Устанавливается в 1, если знаковый бит изменился в той ситуации, когда этого не должно было произойти.

Пусть, например, команда ADD выполнила следующее сложение:

Флаги управления

Влияют на выполнение специальных функций. Эти флажки устанавливаются лишь несколькими специальными инструкциями. Это флажки:

60

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]