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

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

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

Наиболее простым способом объединения частей программы, написанных на Си и ассемблере, является использование в тексте встроенного (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. Ассемблирование таким образом сохраняет

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