Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
МУ_ЛЕК.doc
Скачиваний:
0
Добавлен:
01.03.2025
Размер:
801.79 Кб
Скачать

Описание процедур

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

имяP PROC [параметры] ; начало процедуры имяP

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

RET ; КОМАНДА возврата в точку вызова процедуры

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

имяP ENDP ; конец процедуры имяP

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

Обратите внимание на ОБЯЗАТЕЛЬНУЮ команду RET. Она может быть в любом нужном месте процедуры и НЕ единственная. Если ее в процедуре НЕ будет, то ассемблерная программа НЕ сможет нормально работать — возникнет зависание.

Описание внешних ссылок

Как было заявлено ранее, мы будем использовать алгоритмические языки Pascal и C/C++ в качестве помощников при изучении Ассемблера. Таким образом, сразу начинаем работать с РАЗНЫМИ модулями, да еще и на разных языках! Поэтому нам не миновать ВНЕШНИХ ссылок. Что это такое? Это — использование в одном модуле имен, описанных в других модулях.

Директива описания общих имен public

PUBLIC [язык] имя1[,[язык] имя2…]

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

Например, если мы хотим использовать в языке С/С++ функцию с именем Prim, реализованную в Ассемблере, то она в ассемблерном модуле должна быть описана следующим образом:

Public C Prim

Prim Proc

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

Prim EndP

Обратите внимание

Язык С/С++ различает регистр букв в именах. Это же должен делать и Ассемблер, для чего служит специальный ключ, определяющий чувствительность Ассемблера к РЕГИСТРУ выбора символов: ml=all (все символы), mx=globals (только глобальные), mu=none (символы к регистру НЕ чувствительны — принято по умолчанию):

TASM имя.asm[ /ml]

TASM имя.asm[ /mx]

TASM имя.asm[ /mu]

В нашем случае ассемблерный модуль должен быть откомпилирован ОБЯЗАТЕЛЬНО с ключом /ml или /mx. Иначе компоновщик С/С++ НЕ сможет подключить ассемблерный модуль. Если эти рассуждения вам пока НЕПОНЯТНЫ, НЕ зацикливайтесь, — мы к этому еще вернемся на КОНКРЕТНЫХ примерах.

Директива описания внешних имен extrn

EXTRN имя1:тип1[, имя2:тип2…]

Эта директива указывает компилятору и компоновщику, что данное имя имеет определенный тип, его предполагается использовать в данном ассемблерном модуле, но память для него выделена в другом модуле. Параметр тип может принимать следующие значения: ABS (для констант), BYTE, WORD, DWORD, QWORD, TBYTE, FAR, NEAR.

Например, в модуле на алгоритмическом языке Pascal (Borland/Turbo Pascal-5.5/6.0/7.0х) мы описали следующие глобальные переменные:

Var a, b, c : Integer;

X : LongInt;

А использовать их собираемся в ассемблерном модуле. В этом случае директива будет иметь вид:

Extrn a:Word, b:Word, c:Word, x:Dword

Обратите внимание

Язык Pascal НЕ различает регистр букв в именах. А директива EXTRN содержит только ОДНУ гласную букву — начинающие программисты часто на этом спотыкаются…

Полный набор инструкций см в справочнике инструкций.

Лекция 4. Основные команды целочисленной арифметики IBM PC.

ТИПЫ ДАННЫХ АССЕМБЛЕРА

 

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

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

 

Простые типы данных

 

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

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

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

db — резервирование памяти для данных размером 1 байт.

dw — резервирование памяти для данных размером 2 байта.

dd — резервирование памяти для данных размером 4 байта.

df — резервирование памяти для данных размером 6 байт;

dp — резервирование памяти для данных размером 6 байт.

dq — резервирование памяти для данных размером 8 байт.

dt — резервирование памяти для данных размером 10 байт.

 

Напомним порядок размещения данных в памяти. Он напрямую связан с логикой работы микропроцессора с данными. Микропроцессоры Intel требуют следования данных в памяти по принципу: младший байт по младшему адресу.

Команды пересылки данных общего назначения

К этой группе относятся следующие команды:

mov <операнд назначения>,<операнд-источник>

xchg <операнд1>,<операнд2>

 

mov - это основная команда пересылки данных. Она реализует самые разнообразные варианты пересылки.

Отметим особенности применения этой команды:

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

К примеру, рассмотрим фрагмент программы для пересылки байта из ячейки fls в ячейку fld:

        mov     al,fls

        mov     fld,al

 

Нельзя загрузить в сегментный регистр значение непосредственно из памяти. Поэтому для выполнения такой загрузки нужно использовать промежуточный объект. Это может быть регистр общего назначения или стек.

Нельзя переслать содержимое одного сегментного регистра в другой сегментный регистр. Это объясняется тем, что в системе команд нет соответствующего кода операции. Но необходимость в таком действии часто возникает. Выполнить такую пересылку можно, используя в качестве промежуточных все те же регистры общего назначения. Вот пример инициализации регистра es значением из регистра ds:

        mov     ax,ds

        mov     es,ax

Но есть и другой, более красивый способ выполнения данной операции — использование стека и команд push и pop:

        push    ds      ;поместить значение регистра ds в стек

        pop     es      ;записать в es число из стека

 

Нельзя использовать сегментный регистр cs в качестве операнда назначения. Причина здесь простая. Дело в том, что в архитектуре микропроцессора пара cs:ip всегда содержит адрес команды, которая должна выполняться следующей. Изменение командой mov содержимого регистра cs фактически означало бы операцию перехода, а не пересылки, что недопустимо.

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