Яковлев Л.А., Тимченко В.И. Вычислительная техника. Методические указания к лабораторным работам - файл n1.docx

Яковлев Л.А., Тимченко В.И. Вычислительная техника. Методические указания к лабораторным работам
скачать (298.5 kb.)
Доступные файлы (1):
n1.docx299kb.07.07.2012 02:54скачать

n1.docx

1   2   3   4   5   6   7   8

Результат вычисления операнда директивы может быть величиной в 2 байта. Операнд в команде MVI может быть величиной размером в 1 байт; поэтому для команды MVI B,567+(6+7) транслятор выдал сообщения об ошибке ERROR 30 и ERROR 22, которое состоит в том, что операнд находится вне допустимого диапазона (-128...+255). Для команды LXI , которая загружает величину в пару регистров, допускается операнд величиной в 2 байта.

Средства макроассемблера

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

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

Рассмотрим здесь только макрокоманды.

Макрокоманды

При разработке программ часто возникает необходимость в повторении (иногда с модификациями, при других параметрах) некоторой группы команд. Такие группы повторяющихся команд можно оформить как процедуру или подпрограмму. Макроассемблер позволяет применить другой вариант краткой ссылки на часто используемую последовательность команд: такую последовательность можно определить один раз как большую команду - макрокоманду с уникальной мнемоникой, не совпадающей с мнемоникой команд процессора. Макрокоманду после определения ее в начале программы можно рассматривать как входящую в систему команд процессора.

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

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

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

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

Из макрокоманд можно создать библиотеку. Макрокоманды могут быть вложенными друг в друга.

Макроопределение и макровызов

Макроопределением является набор исходных ассемблерных строк, включающий команды процессора, макрокоманды и директивы ассемблера, который должен выполняться процессором в соответствии с определяемой макрокомандой.

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

Макроопределение обычно имеет следующую структуру:

<имя макрокоманды> директива начала % MACRO [список параметров] [ комментарий]

………………………………..

последовательности команд и директив тело макрокоманды

………………………………

директива конца макро %ENDM

Директива начала %MACRO и директива конца макро %ENDM являются макродирективами, т.е. директивами, которые открывают и завершают макроопределение соответственно.

Имя макрокоманды размещается в поле метки, т.е. начинается с первой позиции ассемблерной строки. Последовательность параметров макрокоманды [список параметров] записывается через запятую в поле операнда ассемблерной строки. Параметры в макроопределении являются формальными и заменяются на фактические после макровызова. Макроопределение может не иметь параметров. Через параметры в макроопределении могут задаваться любые операнды и метки.

Макровызов имеет следующую структуру:

[метка] <имя макрокоманды> [список параметров] [ комментарий]

Имя макрокоманды, расположенное в поле мнемоники команды, должно совпадать с именем, расположенным в поле метки соответствующего макроопределения.

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

Пример 1. Макрокоманда без параметров. В соответствии с данной макрокомандой величина, находящаяся в аккумуляторе умножается на три. Результат остается в А.

UMN3 %macro           MOV C,A

RLC ; сдвиг влево на 1 разряд эквивалентен умножению на 2

ADD C

%endm

Транслятор вместо использованных в тексте программы двух макровызовов этой макрокоманды

UMN3

UMN3

подставит макрорасширения (фрагмент взят из листинга)

;UMN3 ; исходная макрокоманда превращена в комментарий

MOV    C,A

RLC

ADD    C

;UMN3 ; исходная макрокоманда превращена в комментарий

MOV    C,A

RLC

ADD    C

Пример 2. Макрокоманда T1 с параметрами и директивой. Макрокоманда использует 4 формальных параметра р1, р2, р3, р4. Используемому внутри макрокоманды символу S присваивается некоторое значение. Так как символ S зависит от параметра и используется только внутри данной макрокоманды, он может принимать при каждом вызове макрокоманды другое значение, поэтому директивой %local он объявляется локальным, т.е. используемым только внутри команд, соответствующих одной макрокоманде.

T1          %macro                  p1,p2,p3,p4

     %local                    s

S            equ                          P1

     MVI                          A,P2+S

     MVI                          B,P3+S

     MVI                          C,P4+S

    %endm

Транслятор вместо использованных в тексте программы двух макровызовов этой макрокоманды

T1         2,3,4,5

T1         6,7,8,9

подставит макрорасширения (фрагмент взят из листинга)

;T1 2,3,4,5 ; исходная макрокоманда превращена в комментарий

??0000 equ 2

MVI     A,3+??0000

MVI     B,4+??0000

MVI     C,5+??0000

;T1         6,7,8,9 ; исходная макрокоманда превращена в комментарий

??0001                         equ     6

MVI     A,7+??0001

MVI     B,8+??0001

MVI     C,9+??0001

Транслятор вместо локального символа S для каждого макрорасширения подставляет свою перемещаемую величину ??0000 и ??0001 , абсолютное значение которой будет определено после компоновки. Вместо формальных параметров p2, p3, p4 подставляются фактические параметры, задаваемые в макрорасширениях.

Пример 3. Макрокоманда с параметром и локальными метками. Внутри тела макрокоманды в зависимости от результата выполнения команды SUI   p производятся условные и безусловные переходы. Так как при каждом вызове макрокоманды адреса переходов будут различны (соответствующие метки переходов должны стоять в разных местах), директивой %local метки, обозначающие адреса переходов, объявляются локальными.

DEL

%macro

p

 

%local

L1

L1

SUI

p

 

%local

L2

 

JP

L2

 

%local

L3

 

JMP

L3

L2

INR

C

 

JMP

L1

L3

 

 

 

%endm

 

Транслятор вместо использованных в тексте программы двух макровызовов этой макрокоманды

DEL 3

DEL 4

подставит макрорасширения (фрагмент взят из листинга)

??0000

;DEL

3

 

SUI

3

 

JP

??0001

 

JMP

??0002

??0001

INR

C

 

JMP

??0000

??0002

 

 

 

;DEL

4

??0003

SUI

4

 

JP

??0004

 

JMP

??0005

??0004

INR

C

 

JMP

??0003

??0005

 

 

Транслятор вместо локальных меток L1, L2, L3 для каждого макрорасширения подставляет свои величины, абсолютное значение которых будет определено после компоновки. Вместо формального параметра p подставляются фактические параметры, задаваемые в макрорасширениях.

Организация библиотеки макрокоманд

Для того чтобы не включать в каждый исходный текст программ макроопределения, из них можно организовать библиотеку, объединив их в один файл на языке ассемблера. Например, из приведенных выше трех макроопределений можно организовать файл lib.asm, текст которого приведен ниже.

* тексты макроопределений

UMN3 %macro

MOV C,A

RLC

ADD C

%endm

T1 %macro p1,p2,p3,p4

%local s

s equ p1

MVI A,p2+s

MVI B,p3+s

MVI C,p4+s

%endm

DEL %macro p

%local L1

L1 SUI p

%local 2

JP L2

%local L3

JMP L3

L2 INR C

JMP L1

L3:

%endm

Обратите внимание: этот файл не должен заканчиваться директивой end.

По мере необходимости в файл библиотеки можно добавлять новые макроопределения.

Включить эту библиотеку в исходный текст программы можно с помощью команды препроцессора %include. Например, библиотеку lib.asm можно включить в текст программы следующим образом

* пустая строка

%include lib.asm

ms: MVI C,5

MVI ,1

mi: MVI B,4

MOV A,C

UMN3

UMN3

T1 2,3,4,5

T1 6,7,8,9

DEL 3

DEL 4

mn: MOV a,b

end

Обратите внимание: команда %include не должна располагаться в первой строке программы.

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

Основные директивы и команды препроцессора ассемблера

Директивы

Основные директивы уже упоминались в предыдущих разделах. Перечислим их еще раз.

Директива end

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

Директивы equ, teq

Директивы используются для присваивания значений символам. Они имеют следующий формат

<символ>] equ <выражение> [; комментарий]

<символ>] teq <выражение> [; комментарий]

Пример

Z equ 5 ; символу z присваивается значение 5

t equ Z+3 ; символу t присваивается значение 8

t1 teq t+t/z ; символу t1 присваивается значение 9

В соответствии с данными директивами символу, стоящему в поле метки (в первой позиции) присваивается результат вычисления выражения, стоящего в поле операнда. Если в выражении используется символ, то он должен быть определен ранее (выше в программе). Разница между директивами equ, teq состоит в том, что символ, определенный директивой teq далее в программе может быть переопределен с помощью этой же директивы.

Директивы extern, public

Директивы используются для определения одних и тех же символов в различных программных модулях при использовании нескольких исходных модулей для получения конечной выполняемой программы. Формат директив:

extern <список символов>

public <список символов>

Пример

extern z

public k,x1,I

Директива extern z означает, что символ z не определяется в данном программном модуле, а будет определен в другом программном модуле, с которым данный будет объединен при компоновке. Символ, объявленный директивой extern, может быть также определен в командном файле компоновки. Транслятор отложит его вычисление до компоновки.

Директива public k,x1,i означает, что символы k,x1,i , значение которых определяется в данном программном модуле, будут также использованы в других. Транслятор запомнит их значение в выходном объектном модуле для использования при компоновке (в противном случае после присваивания значений транслятор “забывает” символы).

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

extern           z

public            k,x1,i

x                 equ                 1+2

t                  equ                  Z+3

k                 equ                  +7

I                  equ                 -7

x1              equ                 10

x5              equ                 t+1

Y                equ                x1*t

X2             equ                 z*t

X3             equ                 5/z

Как видно из примера программы, неопределенные символы могут использоваться в выражениях, однако последнее выражение 5/z вызовет сообщение об ошибке при трансляции (деление на 0), так как в общем случае z может быть равно 0. Поэтому подобные выражения недопустимы.

Директивы db, dw, ds

Директивы используются для резервирования ячеек памяти и размещения в памяти констант и начальных значений переменных. Формат директив:

[метка] db <список выражений>

[метка] dw <список выражений>

[метка] ds <список выражений>

Примеры

M1     db     3,4.5.6

M2     db     3*4,5/2

В соответствии с данными директивами при загрузке программы в память в отдельные ее ячейки (в соответствии с размещением директивы в тексте программы) будут записаны величины 3, 4, 5, 6, результаты вычисления выражений 3*4 и 5/2. Метки в этих директивах являются необязательными элементами. Если они присутствуют, то они являются символическими адресами ячеек, в которых размещены константаны. Так М1 будет являться адресом ячейки, где расположена константа 3, а М2 адресом ячейки с константой 3*4.

Директива db размещает в ячейках значения длиной в байт. Директива dw размещает в двух последовательных ячейках слова длиной в 2 байта.

Пример

М3     dw     0AC5Eh

В соответствии с данной директивой в ячейку с символическим адресом М3 будет записано число 0Ach, а в следующую - число 5Eh.

Директива ds резервирует (оставляет пустыми) в памяти для последующего использования при выполнении программы заданное число ячеек.

М3     ds     6

В соответствии с данной директивой в памяти будет зарезервировано 6 ячеек памяти. Первой пустой ячейке будет присвоен символический адрес М3. место резервирования ячеек определяется расположением директивы в программе.

Директива include

Директива используется для включения одного файла в другой. Формат директивы

include <имя файла>

Следует отметить следующее. Включаемый файл не должен содержать в конце директиву end, так как после выполнения директивы include в середине основного окажется директива end, а транслятор ничего после нее воспринимать не будет. Включаемый файл должен находится в рабочей директории. Директиву include нельзя использовать для включения в файл макроопределений, для этого используется команда препроцессора %include.

Команды препроцессора

Команды препроцессора были рассмотрены в подразделе “Средства макроассемблера”. Напомним их назначение.

Команда %include используется для включения в файл библиотеки макрорасширений.

Команды %macro и %endm определяют начало и конец макроопределения.

Построение простой программы

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

Основная программа test.asm

 

extern          x1,two

 

 

%include    lib1.asm

; включение библиотеки макрорасширений

z

equ              5

 

t

equ              x1+3

 

k

equ              +7

 

i

equ              - 7

 

 

include init.asm

; включение команд инициализации процессора

Begin

MVI      A,x1

 

 

UMN3

 

 

MVI      B,z

 

 

   MVI       C,k+i

 

 

ADI       t

 

 

SUI       two

 

M1

   T1          z,t,k,i

 

 

   MOV      D,A

 

 

   PUSH    B

 

 

  MVI         B,1

 

 

   POP       B

 

 

include stack.asm

; резервирование памяти для стека

 

end

 

Программа не имеет какого либо содержательного смысла и носит чисто учебный характер для отражения различных возможностей ее построения. В программе используются объявленные директивой extern символы x1,two, значение которых будет определено при компоновке. В программе используются макрокоманды UMN3 и T1 z,t,k,i. Макроопределения этих команд записаны в библиотеке lib1.asm и включаются в основную программу командой препроцессора %include. Использованные макрокоманды описаны в подразделе “Средства макроассемблера”.

Файл lib1.asm

* тексты макроопределений

UMN3

 

%macro

 

 

 

MOV        C,A

 

 

 

RLC

 

 

 

ADD         C

 

 

 

%endm

 

T1

 

%macro

p1,p2,p3,p4

 

%local

   s

 

s

 

equ

p1

 

MVI

A,p2+s

 

 

 

MVI         B,p3+s

 

 

 

MVI         C,p4+s

 

 

 

%endm

 

В начале программы обычно записываются команды инициализации процессора; они могут задавать различные режимы, а также в первую очередь они должны определять таблицу векторов прерываний, организацию стека и разрешение прерываний (если прерывания и стек используются в программе). Соответствующие команды можно писать прямо в тексте программы. Поскольку эти действия носят типовой характер и могут повторяться в других программах, они могут быть вынесены в отдельный файл и включены в основную программу директивой include. В приводимом примере команды инициализации процессора записаны в файле init.asm. Таблица векторов прерывания обычно занимает 64 ячейки, и основная программа начинается с 64 (40h). Для выполнения этого условия в приводимом файле с помощью директив ds пропускаются пустые ячейки.

Файл init.asm

 

JMP

INIT

; таблица векторов прерывания

 

ds

5

 

 

JMP

M1

 

 

ds

53

 

INIT

LXI

SP,stack

; начало программы, организация стека -

 

 

 

; запись в указатель символического адреса

 

 

 

; вершины стека

 

EI

 

; разрешение прерываний

 

JMP

BEGIN

; переход к основным действиям

Стек размещается в основной памяти процессора. Его обычно размещают в памяти после основной программы. Так как заполнение стека идет вниз (в сторону уменьшения адресов), после конца программы директивой ds резервируется 20 ячеек для стека. Символический адрес вершины стека stack будет соответствовать концу зарезервированной области памяти.

Файл stack.asm

 

ds

20

 

stack

 

 

;вершина стека
1   2   3   4   5   6   7   8


Учебный материал
© nashaucheba.ru
При копировании укажите ссылку.
обратиться к администрации