Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Вопросы 20,22,23.docx
Скачиваний:
2
Добавлен:
01.04.2025
Размер:
43.58 Кб
Скачать

Вопрос 20

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

Нас интересуют 3 вопроса: как передать аргументы в процедуру на ассемблере, как к ним обратиться в процедуре на ассемблере и как возвратить результат? В начале отметим, что всегда нужно сохранять содержимое регистров BP, SP, CS, DS, SS. Это делается перед вызовом процедуры. Остальные регистры нужно сохранять по необходимости

Rомпиляторы языков C/C++ разраба­тываются множеством фирм — в отличие от Pascal, компилятор для которого вы­пускает практически одна фирма Borland. Это обстоятельство, на мой взгляд, — основная причина сложности связи С—ассемблер, так как каждая фирма реализу­ет ее по-своему (хотя суть и остается практически неизменной). Поэтому, как мне кажется, нет смысла рассматривать множество частных случаев.

Как правило, компиляторы позволяют связывать модули на C/C++ и ассемб­лере с использованием средств командной строки. Так как этот процесс довольно хорошо стандартизован, есть смысл его рассмотреть. В качестве примера выберем компилятор С++ 5.0 фирмы Inprise. Типовая последовательность шагов выглядит примерно так:

  1. Составить текст программы на С++, объявить процедуру asmproc внешней:

extern void asmproc(char ch, unsigned x, unsigned y, unsigned kol);

  1. Выполнить трансляцию модуля С++ и получить объектный модуль:

Ьсс -с prgi5_l9.cpp

Параметр -с здесь означает, что выполняется только компиляция исходного файла, загрузочный модуль не создается

  1. Составить текст процедуры на ассемблере в которой объ­явить процедуру asmproc общедоступной с помощью директивы PUBLIC. Заметьте, что идентификатору asmproc предшествует символ подчеркивания (_asmproc). Компилятор C/C++ добавляет знак подчеркивания ко всем глобальным иден­тификаторам. Более того, некоторые компиляторы (VC++) могут кроме сим­вола подчеркивания добавлять в конце исходного идентификатора комбина­цию символов @nn, где nn означает количество байтов, занимаемых аргументами процедуры в стеке

  2. Выполнить трансляцию программы на ассемблере:

tasm prgl5_20,,,

  1. Выполнить объединение объектных модулей:

bcc -ms prgl5_19.obj prgl5_20.obj

Как возвратить результат в программу на С из процедуры на ассемблере? Для этого существуют стандартные соглашения (табл. 15.3). Перед возвратом управ­ления в программу на С в программе на ассемблере необходимо поместить резуль­тат или сформировать указатель в заданных регистрах.

Тип возвращаемого значения в С++

Место записи результата

Unsingned char

AX

Char

AX

Emum

AX

Unsigned short

AX

Short

AX

Unsingned int

AX

Int

AX

Unsingned long

DX-AX

Long

DX-AX

Указатель near

AX

Указатель far

DX-AX

Обратите внимание на то, что листинг 15.19 содержит текст исходного файла срасширением .срр, а листинг 15.21 — с расширением .с. Соответственно, сами ис­ходные тексты в части организации межмодульного взаимодействия также разли­чаются.

Листинг 15.19. Вызывающий модуль на С++

//prgl5_19.cpp

#include <stdio.h>

#include <conio.h>

extern "C" void asmproc(char ch, unsigned x, unsigned у.unsigned kol);

void main (void)

{

clrscrO;

asmproc('a4,2,3,5);

asmprocCs' , 9. 2, 7);

}

Листинг 15.21. Вызывающий модуль на C/C++

/ * р г g15_21.с*/

#include <stdio.h>

extern int sum_asm(int mass1v[],1nt count);

main()

{

int mas[5] = {1,2,3,4,5};

int len=5; int sum;

sum=sum_asm(mas,len);

printf ("%d\n" .sum) ;

return(0) ;

}

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]