Скачиваний:
27
Добавлен:
15.06.2014
Размер:
33.28 Кб
Скачать

Интерфейс программ на языке ассемблера с программами на языке Си.

Вызов ассемблера из Си.

Наиболее простым способом объединения частей программы, написанных на Си и ассемблере, является использование в тексте встроенного (in - line) ассемблера.

Любая строка Си - программы начинающаяся с ключевого слова asm, до символа ';' или символа перевода строки рассматривается как инструкция на ассемблере.

Для встроенного ассеблера разрешается использовать:

1. исполняемые инструкции (машинные комманды);

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

3. все инструкции передач управления (JUMP, CALL, LOOP, RET, IRET) с прямой или косвенной адресацией;

4. директивы описания распределения данных (db, dw, dd, extrn).

Для встроенного ассемблера нельзя использовать его директивы, управляющие его работой: ASSUME, SEGMENT, ENDS, PROC, ENDP, ORG и т.д.

При задании операндов в ассемблерных инструкциях разрешается ссылаться на уже описанные переменные Си функции, поля структурных переменных и объединений, метки, имена функций и т.п.

В ассемблерных инструкциях нельзя использовать имя группы DGROUP, имена сегментов _TEXT, _STACK, _DATA и т.п.

Рассмотрим пример простейшей программы, выполняющей суммирование двух целых чисел. Ввод и вывод производятся в Си, а сложение - в ассемблере.

#pragma inline /* эта деректива указывает компилятору на то, что

в программе есть ассемблерные строки*/

void main()

{

int i,j,s;

puts("Введите значения i и j");

scanf("%d%d",&i,&j); /* ввод значений i и j */

asm push ax /* значение регистров ax и bx */

asm push bx /* помещается в стек */

asm mov ax,i /* в ах заносится введенное значение i */

asm mov bx,j /* в bx заносится введенное значение j */

asm add ax,bx /* сумма ax и bx сохраняется в ax */

asm mov s,ax /* содержимое ax передается в s */

asm pop bx /* из стека востанвливаются */

asm pop ax /* значения регистров ax и bx */

printf("i + j = %d\n",s); /* вывод результата */

}

Эту же программу можно записать по другому:

#pragma inline

void main()

{

int i,j,s;

puts("Введите значения i и j");

scanf("%d%d",&i,&j);

asm

{

push ax bx

mov ax,i

mov bx,j

add ax,bx

mov s,ax

pop bx ax

}

printf("i+j=%d\n",s);

}

Если имеются переменные, описанные в пределах ассемблерного модуля на который выполняется ссылка в Си-функции, то они объявляются как PUBLIC:

PUBLIC имя_переменной

Имя ассемблерной процедуры, вызываемой из Си, в ассемблерном блоке должно описываться как PUBLIC, что делает это имя видимым при редоктировании связей.

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

1. При объявлении внешнего идентификатора, в том числе и имен функций, которые по умолчанию являются внешними, компилятор Си автоматически добавляет символ подчеркивания "_" перед именем и в таком виде сохраняет его в объектном модуле.

В то же время ассемблеры TASM и MASM не добавляют символ подчеркивания.

2. Компилятор TURBO C для всех внешних идентификаторов сохраняет регистр букв, т.е. является "регистрочувствительным" (case sensetive), и такое поведение Си компилятора не возможно изменить. В тоже время TASM и MASM при записи внешних идентификаторов в объектном модуле приводят их к верхнему регистру, т.е. все малые буквы преобразовываются в большие. Такое поведение по умолчанию можно переопределить, используя опцию /mx. Ассемблирование таким образом сохраняет регистр букв глобальных идентификаторов.

Вызов функции Си из программ на языке ассемблера.

Необходимость вызова Си функций из ассемблерной процедуры, как правило, возникает при использовании библиотечных функций Turbo C, выполняющих ввод-вывод.

На Си разрабатывается головная функция main(), содержащая единственную строку - вызов ассемблерной процедуры. Она ассемблируется в .obj файл, подключаемому к головному модулю через файл проекта. После этого ассемблерная процедура может вызывать любую библиотечную функцию Turbo C или Си - функцию, в составе которой имеется обращение к библиотечным функциям.

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

Имя вызываемой Си функции должно быть описано как near или far указатели на функции директивой:

EXTRN name_function: {far | near}

тип указателя должен соответсвовать модели памяти, с использованием которой компилировалась Си функция.

имя функции записывается с лидирующим символом подчеркивания строчными буквами.

Соседние файлы в папке Ответы на билеты