Связь и интернет Архив Программирование
   
Сделать стартовойСделать закладку            
   ПОИСК  
   
Главная / Турбо Ассемблер / Использование Турбо Ассемблера /
8  Perl
8  PHP
8  JavaScript
8  HTML
8  DHTML
8  XML
8  CSS
8  C / C++
8  Pascal и Delphi
8  Турбо Ассемблер
8  MySQL
8  CASE-технологии
8  Алгоритмы
8  Python
8  Обратная связь
8  Гостевая книга
Новости о мире


Интерфейс Турбо Ассемблера с Турбо Паскалем - Программирование от RIN.RU
Интерфейс Турбо Ассемблера с Турбо Паскалем



Обеспечение стека


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


Есть два способа настройки стека. Вы можете использовать инструкцию RET N (где N - это число байт передаваемых, то есть занесенных в стек, параметров), либо сохранить адрес возврата в регистрах (или в памяти) и извлечь параметры из стека поочередно. Такую технику извлечения полезно использовать для оптимизации по скорости при работе с процессором 8086 или 8088 (самые "медленные" процессоры серии), когда на адресацию типа "база плюс смещение" затрачивается минимум 8 циклов за обращение. Это позволяет также сэкономить место, так как инструкция POP занимает только один байт.


Примечание: Если вы используете директивы .MODEL, PROC и ARG, то Ассемблер автоматически добавляет во все инструкции RET число байт извлекаемых параметров.


Доступ к параметрам


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


Примечание: При вычислении адресов параметров нужно принимать во внимание регистры, такие как BP, содержимое которых также может быть занесено в стек.)


Существует три основных метода доступа к параметрам, передаваемых Турбо Паскалем вашей подпрограмме на Турбо Ассемблере. Вы можете:


  • использовать для адресации к стеку регистр BP;

  • для получения параметров использовать другой базовый или индексный регистр;

  • извлечь из стека адрес возврата, а затем параметры.




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


Использование для адресации к стеку регистра BP


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


CODE

MyProc

j

i









SEGMENT
ASSUME CS:CODE
PROC FAR
PUBLIC MyProc
EQU WORD PTR [bp+6]

EQU WORD PTR [bp+8]
push bp

mov bp,sp

mov ax,i
.
.
.


; procedure MyProc(i,j : integer);

; j находится над сохраненным BP
; и адресом возврата
; i располагается над j
; нужно сохранить BP вызывающей
; программы
; BP теперь указывает на вершину
; стека
; адресуемся к i через BP






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


Обратите внимание на использование в данном примере присваиваний. Они позволяют сделать программу более понятной. У них есть только один недостаток: поскольку для выполнения такого рода присваиваний можно использовать только директиву EQU (а не =), в данной исходном файле Турбо Ассемблера вы не сможете переопределить идентификаторы i и j. Один из способов обойти это заключается в том, чтобы использовать более описательные имена параметров, чтобы они не повторялись, либо можно ассемблировать каждую подпрограмму Ассемблера отдельно.


Директива ARG


Хотя можно обращаться к параметрам через регистр BP, Турбо Ассемблер предусматривает альтернативу вычислению смещений в стеке и выполнению текстовых присваиваний. Это директива ARG. При использовании ее в процедуре директива ARG автоматически определяет смещения параметров относительно регистра BP. Она вычисляет также размер блока параметров и использует его в инструкции RET. Поскольку идентификаторы, создаваемые по директиве ARG, определены только в соответствующей процедуре, в каждой процедуре или функции вам не требуется использовать уникальные имена параметров.


Покажем, как будет выглядеть пример предыдущего раздела, если переписать его, используя директиву ARG:


CODE SEGMENT
ASSUME CS:CODE
MyProc PROC FAR ; procedure MyProc(i,j : integer); external;
PUBLIC MyProc
ARG j : WORD, i : WORD = RetBytes
push bp ; нужно сохранить BP вызывающей программы
mov bp,sp ; BP теперь указывает на вершину стека
mov ax,i ; адресуемся к i через BP
.
.
.


Директива ARG Турбо Ассемблера создает локальные идентификаторы для параметров i и j. На время выполнения процедуры строка:


ARG j : WORD, i : WORD = RetBytes


автоматически приравнивает идентификатор i к [WORD PTR BP+6], идентификатор j к [WORD PTR BP+8], а идентификатор RetBytes - к числу 4 (размеру в байтах блока параметров). В значениях учитывается и занесенное в стек значение BP, и размер адреса возврата: если бы процедура MyProc имела ближний тип, то i было бы приравнено к значению [BP+4], j - к [BP+6], а RetBytes также было бы равно 4 (в любом случае процедура MyProc может завершить выполнение с помощью инструкции RET RetBytes).


При использовании директивы ARG нужно помнить, что параметры должны перечисляться в обратном порядке. Последний параметр процедуры или функции Турбо Паскаля нужно размещать в директиве ARG первым и наоборот.


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


function MyProc(i, j : char) : string; external;


Директива ARG для этой функции должна была бы выглядеть так:


ARG j: BYTE: 2, i:BYTE: 2 = RetBytes RETURN result: DWORD


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


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


Турбо Паскаль и директива .MODEL


Директива .MODEL с параметром TPASCAL задает упрощенную сегментацию, модель памяти и языковую поддержку. Обычно используется большая модель памяти (large) Ранее мы уже видели, что нужно сделать в программах Ассемблера, чтобы можно было использовать процедуры и функции Паскаля. Преобразуем пример, используя в нем директивы .MODEL и PROC:


.MODEL large, PASCAL
.CODE
MyProc PROC FAR i:BYTE,j:BYTE result:DWORD
PUBLIC MyProc
mov ax,i
.
.
.
ret


Заметим, что теперь не нужно задавать параметры в обратном порядке. Не требуется также масса других операторов. Использование в директиве .MODEL ключевого слова PASCAL задает использование соглашений Паскаля, определяет имена сегментов, выполняет инструкции PUSH BP и MOV BP,SP и задает также возврат с помощью инструкций POP BP и RETn (где n - число байт параметров).


Использование другого базового или индексного регистра


Второй способ доступа к параметрам состоит в использовании для получения этих параметров другого базового или индексного регистра (BX, SI или DI). Нужно однако помнить, что по умолчанию сегментным регистром для них является регистр DS, а не SS. Поэтому для их использования вам придется применять префикс переопределения сегмента.


Приведем пример использования для получения параметров регистра BX:


CODE SEGMENT
ASSUME CS:CODE
MyProc PROC FAR ; procedure MyProc(i,j : integer);
PUBLIC MyProc
j EQU WORD PTR SS:[BX+4] ; j находится над сохраненным BP и адресом возврата
i EQU WORD PTR SS:[bp+8] ; i располагается над j
mov bx,sp ; BX теперь указывает на вершину стека
mov ax,i ; адресуемся к i через BX
.
.
.


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


<<<  НазадВперед  >>>
 1  2  3  4  5  6  7  8 


 8  Комментарии к статье  8 8  Обсудить в чате

8  В тему

Начало работы на Турбо Ассемблере

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

Общие принципы программирования

Объектно-ориентированное программирование

Использование выражений и значений идентификаторов

Директивы выбора процессора

Использование моделей памяти программы и сегментации

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

Задание и использование счетчика адреса

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

Управление областью действия идентификаторов

Определение данных

Расширенные инструкции

Использование макрокоманд

Использование условных директив

Интерфейс с компоновщиком

Генерация листинга

Интерфейс Турбо Ассемблера и Borland C++

 
  
  
    Copyright ©  RIN 2003 - 2004      * Обратная связь