profil

C++ - wykład 4/4 cd.

poleca 87% 103 głosów

Treść
Grafika
Filmy
Komentarze

Poniższy przykład demonstruje wywołanie z poziomu C Fortranowskiej funkcji liczącej silnię: fact:

/* C source file - calls FORTRAN function

compile in medium or large memory model */



int __fortran fact(int N);



/* Fortran keyword caises C to use FORTRAN calling and naming convenction.

Integer parameter passed by value */



main()

{

int x=3,y=4;

printf("The factorial of x is %4d",fact(x));

printf("The factorial of y is %4d",fact(y));

printf("The factorial of x+y is %4d",fact(x+y));

}



C FORTRAN source file - factorial function

C

C N is received by value, becausse of VALUE attribute

C NOTRUNCATE - no truncate identifier name to 6 characters

$NOTRUNCATE

INTEGER *2 FUNCTION FACT (N)

INTEGER*2 N[VALUE]

C

INTEGER *2 I

FACT = 1

DO 100 I=1,N

FACT=FACT*I

100 CONTINUE

RETURN

END

Ponieważ w przeciwieństwie do poprzedniego przykładu parametry nie ulegały zmianie zdecydowano przesłać je przez wartość (sposób default dla języka C). Wymagało to określenia atrybutu VALUE dla przesyłanych parametrów w definicji funkcji Fortranowskiej.



Wywoływanie podprogramów Pascalowskich z poziomu C

W pascalu mamy do czynienia z dwoma rodzajami podprogramów: procedurą i funkcją.Procedura nie zwraca wartości, funkcja zwraca.



Procedura Pascalowa wywoływana z poziomu C

Procedura Pascalowska maxparam jest odpowiednikiem takiej samej w języku Fortran:

/* C source file - calls Pascal procedure. Compile in medium or large memory model */

void __pascal maxparam(int __near *a, int __near*b);

/* Declare as void becouse there is no return value.The __pascval keyword causes C to use PASCAL calling and naming convenction. Two integer parameters passed by near adress */

main()

{

int a=5,b=7;



printf("a=%d, b=%d",a,b);

maxparam(&a,&b);

printf("a=%d,b=%d",a,b);

}

{Pascal source code = maxparam procedure }

MODULE Psub;

PROCEDURE Maxparam(var a:integer;var:b:integer);

begin

if a>b then

b:=a

else

a:=b;

end;

end.

W powyższym przykładzie ponieważ parametry przesyłane były przez adress near można było użyć w procedurze słowa VAR. Dla adresu far konieczne byłoby użycie VARS. Konwencja pascalowa określana jest przez słowo kluczowe __pascal



Wywołanie funkcji Pascalowskiej z poziomu C

Funkcja jest odpowiednikiem funkcji z Fortranu:

/* C source file - calls PASCAL function

compile in medium or large memory model */



int __pascal fact(int N);



/* Pascal keyword caises C to use PASCAL calling and naming convenction.

Integer parameter passed by value */



main()

{

int x=3,y=4;

printf("The factorial of x is %4d",fact(x));

printf("The factorial of y is %4d",fact(y));

printf("The factorial of x+y is %4d",fact(x+y));

}

{ Pascal source code - factorial function }

MODULE Pfun;

FUNCTION Fact (n:integer):integer;

begin

fact:=1;

while n>0 do

begin

fact :=fact*n;

n:=n-1;

end;

end;

end.



Dla języka C++ interfejs pomiędzy językiem C++ i innym językiem wyższego poziomu odbywa się poprzez odniesienie do C: extern "C"

{

void prin; // odwołanie do funkcji w języku C

}



extern "C" { int __pascal fact(int n); } //deklaruje funkcję napisaną w konwencji Pascala



Owołanie C do języków asemblerowych

Najczęstszym sposobem pisania "wstawek" asemblerowych jest użycie tzw. inline asemblera. Można również tworzyć samodzielne moduły w dostępnych asemblerach. Jednak asembler "inline" jest bardziej efektywny od samodzielnych asembleró. Oto kilka zalet takiego podejścia:

1. kod asemblera inline włączony jest do kodu języka C. Kod napisany w asemblerach zewnętrznych musi być umieszczony w oddzielnych plikach.

2. krótkie wstawki asemblerowe mogą optymalizować program

3. nie wymagają też wykonywania wywołania funkcji tak jak by to było a asemblerach zewnętrznych . Są to po prostu linie kodu tyle tylko, że w asemblerze

Nie będziemy mówili o asemblerach zewnętrznych. Powiemy tylko parę słów o asemblerze "inline";

Zakres użycia tej techniki jest bardzo szeroki jednak najczęściej stosowany jest do:

- poprawiania szybkości programu

-zmniejsza potrzeby co do zajętości pamięci

-użycie funkcji DOS i BIOS z instrukcja INT

Umożliwia umieszczenie kodu asemblerowego bezpośrednio w kodzie C. Jest wbudowany w kompilator i nie wymaga zewnętrznych asemblerów kod asemblerowy poprzedzony musi zostać słowem kluczowym asm:

__asm

{

mov ah,2

mov dl,7

int 21h

}

kod ten równoważny jest zapisowi:

__asm mov ah,2

__asm mov dl,7

__asm int 21h

Jeśli słowo kluczowe asm używane jest przed każdą instrukcja wtedy mogą być one umieszczone w jednej lini:

__asm mov ah,2 __asm mov dl,7 __asm int 21h

Poniższy przykład ilustruje użycie funkcji napisanej w asemblerze inline wywołanej w kodzie języka C:



#include

int power2(int num,int power);

void main(void)

{

printf("3 times 2 to the powerr of 5 is %d
",power2(3,5));

}

int power2(int num,int power)

{

__asm

{

mov ax,num;

mov cx,power;

shl ax,cl;

}

/* return with result in ax */

}



W bloku __asm możemy wywoływać funkcje biblioteczne języka C: wykonuje to instrukcja CALL:



#include

char format[]="%s %s";

char hello[] = "Hello";

char world[] = "world";



void main(void)

{

__asm

{

mov ax, offset world

push ax

mov ax, offset hello

push ax

mov ax, offset

push ax

call printf

}

}

funkcja printf zbiera swoje argumenty, które umieszczane są na stosie

powyższy kod emuluje zapis C:

printf(format,hello,world);

Czy tekst był przydatny? Tak Nie
Przeczytaj podobne teksty

Czas czytania: 6 minut