osdev.labedz.org

Wywołanie procedury napisanej w języku assemblera z poziomu procedury napisanej w języku C

Wywołanie procedury napisanej w języku assemblera z poziomu procedury napisanej w języku C najczęściej występuje wtedy, gdy dana procedura ma wykonać jakieś operacje niskopoziomowe, a umieszczanie tego kodu w linii języka C powodowało by znaczne zmniejszenie czytelności programu.

Aby wywołać procedurę w assemblerze należy ją najpierw zdefiniować w pliku nagłówkowym:

void load_gdtr(dword gdtr_address);

Dzięki temu taką procedurę można wywoływać w standardowy sposób, tak jak zwykłą procedurę napisaną w języku C.

GLOBAL load_gdtr ... load_gdtr: push ebp mov ebp,esp push ebx mov ebx, [ss:ebp+8] lgdt [ds:ebx] pop ebx pop ebp ret

Argument przekazany z poprzedniej procedury zostaje umieszczony na stosie. Aby mieć do niego dostęp wpierw należy zachować wartość rejestru ESP w rejestrze EBP, dzięki czemu możemy używać stosu, bez zmiany wskaźnika do argumentów. W tym wypadku adres pierwszego argumentu to [SS:EBP+8]. Wartość przesunięcia jest wynikiem sumy wielkości adresu powrotu do poprzedniej procedury i wielkością rejestru EBP zachowanego na stosie (dwa słowa po cztery bajty - w sumie osiem bajtów).

Etykieta procedury w assemblerze powinna być symbolem globalnym, dzięki czemu konsolidator jest w stanie odpowiednio połączyć pliki obiektowe. W tym wypadku aby symbol etykiety był globalny należy umieścić dyrektywę GLOBAL load_gdtr w kodzie programu.