Команды процессора, используемые в лабораторной работе

· MOV– команда передачи данных. Пересылает один элемент данных из регистра в регистр, из регистра в память, из памяти в регистр, выполняет загрузку данных в регистр или память.

Оба операнда должны быть одного и того же размера - байт, слово или двойное слово.

Нельзя выполнять пересылку данных с помощью MOV из одной переменной в другую, из одного сегментного регистра в другой. Кроме того, нельзя помещать в сегментный регистр непосредственный операнд - эти операции выполняются двумя командами MOV (из сегментного регистра в обычный и уже из него в другой сегментный).

· ADD –складывает содержимого операнда-источника и операнда приемника и помещает результат в операнд-приемник.

· SUB – вычитает содержимое операнда-источника из содержимого операнда-приемника и возвращает результат в операнд-приемник.

· INC –добавляет 1 к содержимому регистра или ячейки памяти, указанных в качестве операнда.

· DEC –вычитает 1 из содержимого регистра или ячейки памяти.

· MUL –производит перемножение без знака содержимого регистра АХ или АL с содержимым указанного операнда. При перемножении байтов 16-тиразрядный результат помещается в регистры AH (старший байт) и AL (младший байт), при перемножении слов в регистры DX (старшее слово) и AX (младшее слово). Команда не позволяет использовать в качестве операнда непосредственное значение.

· IMUL –выполняет перемножение чисел со знаком. Работает аналогично команде MUL.

· DIV –делит без знака содержимое регистра AX (при делении на байт) или регистров DX и AX (при делении на 16-разрядное слово) на указанный в команде операнд. В первом случае частное помещается в регистр AL, остаток – в регистр АН. Во втором случае частное помещается в регистр АХ, а остаток – в регистр DX.

· IDIV – предназначена для деления чисел со знаком. Работает аналогично команде DIV.

Директивы определения данных:

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

Директивы определения переменных

– указывают ассемблеру, что в соответствующем месте программы располагается переменная;

– определяют тип переменной (байт, слово, вещественное число и т.д.);

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

Ассемблер обеспечивает два способа резервирования данных: через указание длины данных и по их содержимому. Формат определения данных:

[имя] Dn выражение,

где n – задает тип данных. Так DB – определить байт, DW – определить слово (2байта), DD – определить двойное слово (4 байта), DF – определить 6 байт, DQ – определить учетверенное слово (8 байт), DT– определить 10 байт.

Примеры определения данных:

А1 DB ? – байт с именем А1 принимает неопределенное значение,

COUNT DW 970 – слово с именем COUNT принимает значение 970,

MASKA DB 0FFH – байт с именем MASKA принимает значение FF в шестнадцатеричном коде,

MESSG DB ‘message’ – строка байт, заполненная текстом,

ADDR DW MESSG – в слово с именем ADDR помещается смещение первого байта строки MESSG,

ADDR1 DD MYPROC – в двойное слово с именем ADDR1 помещается адрес процедуры MYPROC,

TABL DW 128 DUP(?) – под переменную TABL резервируется128 неопределенных слов,

KILO EQU 10 – KILO резервируется как значение 10

TABL1 DB KILO DUP(’’) – под переменную TABL1 резервируется 10 байт, содержащих символ’’,

DESB DT ? – под переменную DESB, резервируется10 байт,

OFFS EQU 67+8 – OFFS резервируется как значение 67+8

MASN EQU $- MESSG – MASN определяется значением разности текущего адреса и смещения первого байта строки MESSG

ARRAY DB 6,2,4,1,3 – определение массива символов с именем ARRAY,

BITS DW 0F5E9H – слово с именем BITS принимает значение BITS 0F5E9H в шестнадцатеричном коде,

MEM=9 – значение 9 обозначается как MEM

EXE и COM программы. Программы, выполняемые под управлением MS–DOS, могут принадлежать к одному из двух типов, которым соответствуют расширения имен программных файлов .COM и .EXE. Основное различие этих типов программ заключается в том, что программы типа .COM состоят из единственного сегмента, в котором размещаются и программа, и данные, и стек, а программы типа .EXE состоят из отдельных сегментов для программы, данных и стека. Размер программы типа COM не может превышать максимального размера сегмента, а именно 64 Кбайт, размер же программы типа EXE ограничен только размером памяти.

Структура типичной EXE-программы на ассемблере, подготовленной для ассемблера MASM, выглядит следующим образом.

title ; Программа типа .EXE

data segment ; Сегмент данных

string db «строка данных»,»$»

data ends ; Конец сегмента данных

cseg segment ‘code’; Сегмент программы.

assume CS :cseg, DS:data, SS:stack; ES:data

myproc proc

mov AX,data ; Указание на начало сегмента данных

Mov DS,AX

… ; Текст программы.

mov AH,4Ch ; Выход из программы

int 21h; в DOS.

myproc endp;

cseg ends; Конец сегмента программы.

Stacksegment stack ‘stack’; Организация

dw 128 dup (0); сегмента

stack ends; стека.

end myproc ; Конец программы

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

Рассмотрим структуру программы. Оператор title позволяет следующий за ним текст вывести во все страницы листинга программы в качестве заголовка. Комментарии указываются после знака «;».

Программа состоит из трех сегментов: программного cseg, сегмента данных data и сегмента стека stack. Имена сегментам даются произвольно. Каждый сегмент открывается оператором segment и закрывается оператором ends. Перед обоими операторами должно стоять имя сегмента. Порядок описания сегментов в большинстве случаев значения не имеет, но предпочтительнее данные, используемые в программе, располагать перед текстом программы.

Слова ‘code’ и ‘stack’ указывают на класс сегментов. Сегменты, принадлежащие одному классу, загружаются в память рядом. Когда в памяти используется один сегмент данного класса, этот указатель не обязателен, но для программы – компоновщика LINK необходимо указать класс ‘code’.

Текст сегмента данных в этом примере начинается с одной из типичных команд работы с данными. Команда

String db “строка данных”,”$”

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

Текст программного сегмента начинается с обязательного оператора assume, который позволяет транслятору сопоставить сегментные регистры и символические имена сегментов.

Собственно программа обычно состоит из процедур. Деление программы на процедуры не обязательно, но повышает ее наглядность и облегчает передачу управления подпрограммам и другим программным модулям. В примере программа содержит единственную процедуру myproc, открываемую оператором proc и закрываемую оператором endp c обязательным указанием имени процедуры. Последние две команды программного сегмента

mov ah,4Ch

int 21h

используются для организации возврата в DOS после выполнения программы. При этом вызывается процедура DOS с номером 21h (здесь h указывает на то, что код 21 представлен в 16-тиричном виде) и используется функция 4C, шестнадцатеричный номер которой помещается в регистр АН. Процедура завершает текущий процесс, возвращая указанный код завершения родительскому процессу. В процессе завершения освобождает всю выделенную процессу память, сбрасывает на диск буферы, закрывает все открытые дескрипторы и переда­ет управление обработчику завершения процесса.

В сегментный регистр данных DS данные загружаются через регистр общего назначения AX. В в регистры CS и SS данные загружаются автоматически.

Для правильности выделения стека и автоматической инициализации регистра сегмента стека СS в строке описания сегмента стека необходимо указать параметр stack и класс ‘stack’. Для сегмента стека в программе зарезервировано 128 слов памяти с помощью оператора dw. Для программ, не осуществляющих операций со стеком, определение регистра SS и выделение сегмента стека необязательны. Текст программы заканчивается обязательной директивой end.

Пример программы (. ехе-файл), реализующей вычисление функции у=(a+d)*c/d:

; Вычисление функции у=(а+b)*c/d

; Формат данных – слово.

; ************************************************************

stseg segment para stack 'stack' ;задание сегмента стека

dw 16 dup(?) ; резервирование 16 слов памяти под стек

stseg ends

;–––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––

dseg segment para ;задание сегмента данных

a dw 10

b dw 20

c dw 30

d dw 30

y dw ? ;результат (2 байта)

ostd dw ? ;остаток от деления

dseg ends

;––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––

cseg segment para ;начало сегмента кода

lab1 proc far ; вызов процедуры

assume cs: cseg, ds: dseg,ss: stseg

push ds

mov ax,0

push ax

mov ax,dseg

mov ds,ax

;––––––––––––––––––––––– текст программы ––––––––––––––––––––––––

mov ax,a ; (a)

add ax,b ; (a+b)

imul c ; (a+b)*c

idiv d ;(a+b)*c

mov y,ax ; запись результата в память

mov ost,dx ; запись остатка в память

ret ;возврат изпроцедуры

lab1 endp; конец описания процедуры

cseg ends ; конец сегмента кода

;–––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––

end lab1 ; конец программы

;************************************************************

Наши рекомендации