| |
BIGLIB |
| большущая библиотека (9812 книг), можно не только прочитать но и скачать бесплатно |
|
| |
ФАНТАСТИКА |
| фентези,
фантастика, фантастические повести |
|
| |
ФИЛОСОФИЯ |
книги, которые заставляют
задуматься над окружающим тебя миром.
|
|
| |
МЕДИЦИНА |
медицинские книги,
методички,
народные лечебники |
|
| |
КУЛИНАРИЯ |
рецепты
тортов, консервирование,
все о спиртных
напитках. |
|
| |
СТИХИ |
| стихи популярных
и не очень авторов |
|
| |
ТВОРЧЕСТВО |
| народное творчество,
стихи, песни и т.д. |
|
| |
ЮМОР |
| анекдоты, приколы,
смешные истории |
|
| |
ЭРОТИКА |
| эротические рассказы,
книги о технике секса,
кама-сутра и др. |
|
|
| |
 |
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
Вызываемые из программы на языке С++ функции на Ассемблере,
так же как и функции С++, могут возвращать значения. Значения
функций возвращаются следующим образом:
ЪДДДДДДДДДДДДДДДДДДДДДДДДДДВДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї
іТип возвращаемого значенияі Где находится возвращаемое значениеі
ГДДДДДДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і unsigned char і AX і
і char і AX і
і enum і AX і
і unsigned short і AX і
і short і AX і
і unsigned int і AX і
і int і AX і
і unsigned long і DX:AX і
і long і DX:AX і
і float і регистр вершины стека сопроцессораі
і і 8087 (ST(0)) і
і double і регистр вершины стека сопроцессораі
і і 8087 (ST(0)) і
і long double і регистр вершины стека сопроцессораі
і і 8087 (ST(0)) і
і near* і AX і
і far* і DX:AX і
АДДДДДДДДДДДДДДДДДДДДДДДДДДБДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ
В общем случае 8- и 16-битовые значения возвращаются в ре-
гистре AX, а 32-битовые значения - в AX:DX (при этом старшие 16
бит значения находятся в регистре DX). Значения с плавающей точ-
кой возвращаются в регистре ST(0), который представляет собой ре-
гистр вершины стека сопроцессора 8087 или эмулятора сопроцессора
8087, если используется эмулятор операций с плавающей точкой.
Турбо Ассемблер 3.0/tasm/#2-2 = 103 =
Со структурами дело обстоит несколько сложнее. Структуры,
имеющие длину 1 или 2 байта, возвращаются в регистре AX, а струк-
туры длиной 4 байта - в регистрах AX:DX. Трехбайтовые структуры и
структуры, превышающие 4 байта должны храниться в области стати-
ческих данных, при этом должен возвращаться указатель на эти ста-
тические данные. Как и все указатели, указатели на структуры, ко-
торые имеют ближний тип (NEAR), возвращаются в регистре AX, а
указатели дальнего типа - в паре регистров AX:DX.
Давайте рассмотрим вызываемую из программы на языке С++
функцию на Ассемблере с малой моделью памяти FindLastChar, кото-
рая возвращает указатель на последний символ передаваемой строки.
На языке С++ прототип этой функции выглядел бы следующим образом:
extern char * FindLastChar(char * StringToScan);
где StringToScan - это непустая строка, для которой должен возв-
ращаться указатель на последний символ.
Функция FindLastChar имеет следующий вид:
.MODEL SMALL
.CODE
PUBLIC _FindLastChar
_FindLastChar PROC
push bp
mov bp,sp
cld ; в строковой инструкции нужно
; выполнять отсчет в прямом
; направлении
mov ax,ds
mov es,ax ; теперь ES указывает на
; ближний сегмент данных
mov di, ; теперь ES:DI указывает на
; начало передаваемой строки
mov al,0 ; найти нулевой символ,
; завершающий строку
mov cx,0ffffh ; работать в пределах
; 64К-1 байт
repne scasb ; найти нулевой символ
dec di ; установить указатель
; обратно на 0
dec di ; ссылка обратно на
; последний символ
mov ax,dx ; возвратить в AX указатель
; ближнего типа
pop bp
ret
_FindLastChar ENDP
END
Конечный результат, указатель на передаваемую строку, возв-
ращается в регистре AX.
Турбо Ассемблер 3.0/tasm/#2-2 = 104 =
Вызов функции Турбо Ассемблера из Borland C++
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
Теперь мы рассмотрим пример программы на Borland C++, вызы-
вающей функцию Турбо Ассемблера. Модуль Турбо Ассемблера
COUNT.ASM содержит функцию LineCount, которая возвращает значение
счетчика числа строк и символов в передаваемой строке:
; Вызываемая из С++ функция на Ассемблере с малой моделью памяти
; для подсчета числа строк и символов в завершающейся нулем
; "строке".
;
; Прототип функции:
; extern unsigned int LineCount(char * near StringToCount,
; unsigned int near * CharacterCountPtr);
;
; Ввод:
; char near * StringToCount: указатель на "строку", в
; которой нужно выполнить подсчет строк.
;
; unsigned int near * CharacterCountPtr: указатель на
; целую переменную, в которую нужно записать значение
; счетчика
NEWLINE EQU 0ah ; символ перевода строки в Си
.MODEL SMALL
.CODE
PUBLIC _LineCount
__LineCount PROC
push bp
mov bp,sp
push si ; сохранить регистровую
; переменную вызывающей
; программы
mov si,[bp+4] ; SI указывает на строку
sub cx,cx ; установить значение
; счетчика символов в 0
mov dx,cx ; установить в 0 счетчик
; строк
LineCountLoop:
lodsb ; получить следующий символ
and al,al ; это 0? конец строки?
jz EndLineCount ; да, выполнено
inc cx ; нет, подсчитать следующий
; символ
cmp al,NEWLINE ; это новая строка?
jnz LineCountLoop ; нет, проверить
; следующий символ
inc dx ; да, подсчитать еще одну
; строку
jmp LineCountLoop
EndLineCount:
inc dx ; подсчитать строку, которая
Турбо Ассемблер 3.0/tasm/#2-2 = 105 =
; завершается нулевым символом
mov [bx],cx ; задать значение переменной-
; счетчика
mov ax,dx ; возвратить счетчик строк в
; качестве значения счетчика
pop si ; восстановить регистровую
; переменную вызывающей
; программы
pop bp
ret
_LineCount ENDP
END
Следующий модуль на языке С++ с именем CALLCT.CPP представ-
ляет собой пример вызова функции LineCount:
char * TestString="Line 1\nline 2\nline 3";
extern "C" {
unsigned int LineCount(char * StringToCount,
unsigned int near * CharacterCountPtr); }
main()
{
unsigned int LCount;
unsigned int CCount;
Lcount = LineCount(TestString, &CCount);
printf("Lines: %d\nCharacters: %d\n", LCount, CCount);
}
Два модуля компилируются и компонуются вместе с помощью ко-
мандной строки:
bcc -ms callct.cpp count.asm
Как здесь показано, функция LineCount будет работать только
при компоновке с программами на языке С++, в которых используется
малая модель памяти, так как в других моделях размеры указателей
и адресов в стеке изменятся. Приведем пример версии функции
LineCount (COUNTLG.ASM), которая будет работать с программами на
С++, использующим большую модель памяти (но не малую модель: пос-
кольку передаются дальние указатель, функция LineCount также опи-
сана, как функция дальнего типа):
; Вызываемая из С++ функция на Ассемблере для подсчета числа
; строк и символов в завершающейся нулем "строке".
;
; Прототип функции:
; extern unsigned int LineCount(char * far StringToCount,
; unsigned int far * CharacterCountPtr);
;
|
adfun.ru
|
|
|
|