Interfejsowanie C w trybie 64 bitowym
Interfejsowanie z C w trybie 64 bitowych

W trybie 64 bitowym parametry są przekazywane w pierwszej kolejności nie przez stos ale przez rejestry. Znacznie przyspiesza to wywołanie funkcji.

Przykładowo dla funkcji

 int suma(int a, int b);
argument a bedzie umieszczony w RDI, b natomiast w RSI wynik zwrócony zostanie w RAX.

Program w C
Moduł w assemblerze

Przekazywanie parametrów w trybach 64 bitowych (UNIX)
Pełna specyfikacja 64-bit ABI
Parametry 64-bit - przykład 1
FunkcjaParametry
int f(int      a, 
      double   b, 
      double   c, 
      int      d,
      float    e,
 long double   f,
      char     g,
      long     h,
      int *    i,
      double * j,
      int      k,
      char     l);
RDI
XMM0
XMM1
RSI
XMM2
stos
RDX
RCX
R8
R9
stos
stos
Parametry 64-bit - przykład 2

Uwaga: Jeżeli przesyłamy przez wartość prostą strukturę to jest ona też umieszczana w rejestrach.

typedef struct {
  int a;
  int b;
} Dane;
 
extern int suma(Dane);
...
Dane dane;
int c = suma(dane);

W rejestrze RDI zostanie przesłana cała struktura dane. W starszych 4 bajtach bedzie dane.a, a w młodszych dane.b.

Wynik zwracamy w RAX

Program w C
Moduł w assemblerze

Parametry 64-bit - przykład 3

Jeżeli zwracamy przez wartość prostą strukturę to jeżeli zmieści się ona w rejestrach RAX,RDX,XMM0,XMM1 to tam należy ją umieścić.

Uwaga: musi to już być program C++ bo czyste C nie pozwala zwracać struktur z funkcji.

typedef struct {
  int a;
  int b;
} Dane;
 
extern "C" Dane suma(Dane);
...
Dane dane;
Dane c = suma(dane);

W rejestrze RDI zostanie przesłana cała struktura dane. W starszych 4 bajtach bedzie dane.a, a w młodszych dane.b.

Wynik zwracamy w RAX

Program w C
Moduł w assemblerze

Parametry 64-bit - przykład 4

Jeżeli zwracamy przez wartość dużą strukturę i nie zmieści się ona w rejestrach RAX,RDX,XMM0,XMM1 to do funkcji w RDI zostanie przesłany adres gdzie należy umieścić wynik.

typedef struct {
  int a, b, c, d, e;
} Dane;
 
extern "C" Dane suma(int, int);
...
Dane c = suma(4, 5);

W rejestrze RDI zostanie przesłany adres zmiennej c.
W RSI będzie wartość 4, a w RDX wartość 5.

Wynik wpisujemy bezpośrednio do zmiennej c, a w RAX zwracamy adres zmiennej c

Program w C
Moduł w assemblerze


Tomasz Kapela, Kraków 2011-2020