adfun.ru
| |
BIGLIB |
| большущая библиотека (9812 книг), можно не только прочитать но и скачать бесплатно |
|
| |
ФАНТАСТИКА |
| фентези,
фантастика, фантастические повести |
|
| |
ФИЛОСОФИЯ |
книги, которые заставляют
задуматься над окружающим тебя миром.
|
|
| |
МЕДИЦИНА |
медицинские книги,
методички,
народные лечебники |
|
| |
КУЛИНАРИЯ |
рецепты
тортов, консервирование,
все о спиртных
напитках. |
|
| |
СТИХИ |
| стихи популярных
и не очень авторов |
|
| |
ТВОРЧЕСТВО |
| народное творчество,
стихи, песни и т.д. |
|
| |
ЮМОР |
| анекдоты, приколы,
смешные истории |
|
| |
ЭРОТИКА |
| эротические рассказы,
книги о технике секса,
кама-сутра и др. |
|
|
| |
 |
раметры функциям: вызывающая программа заносит параметры (справа
налево) в стек, вызывает функцию, и извлекает параметры из стека
(отбрасывает их) после вызова. Borland C++ может также работать
по соглашениям, принятым в Паскале. Согласно этим соглашениям па-
раметры передаются слева направо, а отбрасывает параметры (из
стека) вызываемая программа. Разрешить использование соглашений
Паскаля в Borland C++ можно с помощью параметра командной строки
-p или ключевого слова pascal.
Примечание: Более подробно соглашения о связях Паскаля
рассматриваются в Главе 19.
Приведем пример функции на Ассемблере, в которой используют-
ся соглашения Паскаля:
;
; Вызывается, как: TEST(i, j ,k)
;
i equ 8 ; левый параметр
j equ 6
k equ 4 ; правый параметр
;
.MODEL SMALL
.CODE
PUBLIC TEST
TEST PROC
push bp
mov bp,sp
mov ax,[bp+i] ; получить i
add ax,[bp+j] ; прибавить к i j
sub ax,[bp+k] ; вычесть из суммы k
pop bp
ret 6 ; возврат, отбросить
; 6 байт параметров
; (очистка стека)
TEST ENDP
Турбо Ассемблер 3.0/tasm/#2-2 = 111 =
END
Заметим, что для очистки стека от передаваемых параметров
используется инструкция RET 6.
На Рис. 18.5 показано состояние стека после выполнения инс-
трукции MOV BP,SP:
. .
. .
. .
і і
ГДДДДДДДДДДДДДДДДДДДДДДДґ
SP ДД і BP вызывающей прогр. і ДД BP
ГДДДДДДДДДДДДДДДДДДДДДДДґ
SP + 2 і Адрес возврата і BP + 2
ГДДДДДДДДДДДДДДДДДДДДДДДґ
SP + 4 і k і BP + 4
ГДДДДДДДДДДДДДДДДДДДДДДДґ
SP + 6 і j і BP + 6
ГДДДДДДДДДДДДДДДДДДДДДДДґ
SP + 8 і i і BP + 8
ГДДДДДДДДДДДДДДДДДДДДДДДґ
і і
ГДДДДДДДДДДДДДДДДДДДДДДДґ
і і
. .
. .
. .
Рис. 18.5 Состояние стека после инструкции MOV BP,SP
Соглашения по вызовам Паскаля требуют также, чтобы все внеш-
ние и общедоступные идентификаторы указывались в верхнем регистре
и без предшествующих подчеркиваний. Зачем может потребоваться ис-
пользовать в программе на С++ соглашения по вызовам Паскаля?
Программа, использующая соглашения Паскаля, занимает обычно нес-
колько меньше места в памяти и работает быстрее, чем обычная
программа на языке С++, так как для очистки стека от параметров
не требуется выполнять n инструкций ADD SP.
Вызов Borland C++ из Турбо Ассемблера
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
Хотя больше принято для выполнения специальных задач вызы-
вать из С++ функции, написанные на Ассемблере, иногда вам может
потребоваться вызывать из Ассемблера функции, написанные на языке
С++. Оказывается, на самом деле легче вызвать функцию Borland C++
из функции Турбо Ассемблера, чем наоборот, поскольку со стороны
Ассемблера не требуется отслеживать границы стека. Давайте расс-
мотрим кратко требования для вызова функций Borland C++ из Турбо
Ассемблера.
Турбо Ассемблер 3.0/tasm/#2-2 = 112 =
Компоновка с кодом инициализации С++
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
Хорошим правилом является вызов библиотечных функций Borland
C++ только из Ассемблера в программах, которые компонуются с мо-
дулем инициализации С++ (используя его в качестве первого компо-
нуемого модуля). Этот "надежный" класс включает в себя все прог-
раммы, которые компонуются с помощью командной строки TC.EXE или
TCC.EXE, и программы, в качестве первого компонуемого файла кото-
рых используется файл C0T, C0S, C0C, C0M, C0L или C0H.
В общем случае вам не следует вызывать библиотечные функции
Borland C++ из программ, которые не компонуются с модулем инициа-
лизации Borland C++, так как некоторые библиотечные функции
Borland C++ не будут правильно работать, если не выполнялась ком-
поновка с кодом инициализации. Если вы действительно хотите вызы-
вать библиотечные функции Borland C++ из таких программ, мы пред-
лагаем вам взглянуть на код инициализации (файл C0.ASM на дистри-
бутивных дисках Borland C++) и приобрести у фирмы Borland исход-
ный код библиотеки языка С++, после чего вы сможете обеспечить
правильную инициализацию для нужных библиотечных функций.
Вызов определяемых пользователем функций С++, которые в
свою очередь вызывают библиотечные функции языка С++, попадают в
ту же категорию, что и непосредственный вызов библиотечных функ-
ций С++. Отсутствие кода инициализации С++ может вызывать ошибки
в любой программе Ассемблера, которая прямо или косвенно обраща-
ется к библиотечным функциям С++.
Задание сегмента
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
Как мы уже говорили ранее, необходимо обеспечивать, чтобы
Borland C++ и Турбо Ассемблер использовали одну и ту же модель
памяти, и чтобы сегменты, которые вы используете в Турбо Ассемб-
лере, совпадали с теми сегментами, которые использует Borland
C++. В Турбо Ассемблере имеется модель памяти tchuge,которая под-
держивает модель huge Borland C++. Перечень моделей памяти и сег-
ментов можно найти в предыдущем разделе. Нужно не забывать также
помещать директиву EXTRN для внешних идентификаторов вне всех
сегментов или внутри правильного сегмента.
Выполнение вызова
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
Все, что требуется от вас для передачи параметров в функцию
C++, это занесение в стек самого правого параметра первым, затем
следующего по порядку параметра и так далее, пока в стеке не ока-
жется самый левый параметр. После этого нужно просто вызвать
функцию. Например, при программировании на Borland C++ для вызова
библиотечной функции Borland C++ strcpy для копирования строки
SourceString в строку DestString можно ввести:
Турбо Ассемблер 3.0/tasm/#2-2 = 113 =
strcpy(DestString, SourceString);
Для выполнения того же вызова на Ассемблере нужно использо-
вать инструкции:
lea ax,SourceString ; правый параметр
push ax
lea ax,DestString ; левый параметр
push ax
call _strcpy ; скопировать строку
add sp,4 ; отбросить параметры
При настройке SP после вызова не забывайте очищать стек от
параметров.
Можно упростить ваш код и сделать его независимым от языка,
воспользовавшись расширением команды Турбо Ассемблера CALL:
call назначение [язык [,аргумент_1] ...]
где "язык" - это C, PASCAL, BASIC, FORTRAN, PROLOG или
NOLANGUAGE, а "аргумент_n" это любой допустимый аргумент програм-
мы, который может быть прямо помещен в стек процессора.
Используя данное средство, можно записать:
lea ax,SourceString
lea bx,DestString
call strcpy c,bx,ax
Турбо Ассемблер автоматически вставит команды помещения ар-
гументов в стек в последовательности, принятой в С++ (сначала AX,
затем BX), выполнит вызов _strcopy (перед именами С++ Турбо Ас-
семблер автоматически вставляет символ подчеркивания), и очищает
стек после вызова.
Если вы вызываете функцию С++, которая использует соглашения
Паскаля, заносите в стек параметры слева направо. После вызова
настраивать указатель стека SP не требуется.
lea ax,DestString ; левый параметр
push ax
lea ax,SourceString ; правый параметр
push ax
call CTRCPY ; скопировать строку
Можно опять упростить ваш код, воспользовавшись расширением
команды Турбо Ассемблера CALL:
|
adfun.ru
|
|
|
|