Programowanie hybrydowe łączenie C/C++ z asemblerem

Podobne dokumenty
Ćwiczenie nr 6. Programowanie mieszane

Programowanie Niskopoziomowe

Programowanie Niskopoziomowe

PROGRAMOWANIE NISKOPOZIOMOWE. Struktury w C. Przykład struktury PN.06. c Dr inż. Ignacy Pardyka. Rok akad. 2011/2012

Kompilator języka C na procesor 8051 RC51 implementacja

Programowanie niskopoziomowe

Programowanie hybrydowe C (C++) - assembler. MS Visual Studio Inline Assembler

Praktycznie całe zamieszanie dotyczące konwencji wywoływania funkcji kręci się w okół wskaźnika stosu.

PROGRAMOWANIE NISKOPOZIOMOWE. Adresowanie pośrednie rejestrowe. Stos PN.04. c Dr inż. Ignacy Pardyka. Rok akad. 2011/2012

Przedmiot : Programowanie w języku wewnętrznym. Ćwiczenie nr 4

PROGRAMOWANIE NISKOPOZIOMOWE

Tworzenie projektu asemblerowego dla środowiska Visual Studio 2008.

1. Wartość, jaką odczytuje się z obszaru przydzielonego obiektowi to: a) I - wartość b) definicja obiektu c) typ oboektu d) p - wartość

Język ludzki kod maszynowy

Wstęp do programowania

PODSTAWOWE ELEMENTY ASEMBLERA TRYBY ADRESOWANIA. OPERATORY ASEMBLERA

1. Pierwszy program. Kompilator ignoruje komentarze; zadaniem komentarza jest bowiem wyjaśnienie programu człowiekowi.

4 Literatura. c Dr inż. Ignacy Pardyka (Inf.UJK) ASK MP.01 Rok akad. 2011/ / 24

Grzegorz Cygan. Wstęp do programowania mikrosterowników w języku C

Wykład. Materiały bazują częściowo na slajdach Marata Dukhana

Laboratorium 1 Temat: Przygotowanie środowiska programistycznego. Poznanie edytora. Kompilacja i uruchomienie prostych programów przykładowych.

1 Podstawy c++ w pigułce.

Podstawy Programowania. Wykład 1

Programowanie w C++ Wykład 1. Katarzyna Grzelak. 26 luty K.Grzelak (Wykład 1) Programowanie w C++ 1 / 28

Wstęp do programowania

METODY I JĘZYKI PROGRAMOWANIA PROGRAMOWANIE STRUKTURALNE. Wykład 02

Podczas dziedziczenia obiekt klasy pochodnej może być wskazywany przez wskaźnik typu klasy bazowej.

Podstawy programowania skrót z wykładów:

1 Podstawy c++ w pigułce.

Przeciążenie (przeładowanie nazw) funkcji

1 P roste e t ypy p d a d n a ych c - c ąg ą g d a d l a szy 2 T y T py p z ł z o ł żo ż ne e d a d n a ych c : T BLICE

C++ wprowadzanie zmiennych

PROGRAMOWANIE NISKOPOZIOMOWE. Systemy liczbowe. Pamięć PN.01. c Dr inż. Ignacy Pardyka. Rok akad. 2011/2012

Instrukcja do ćwiczenia P4 Analiza semantyczna i generowanie kodu Język: Ada

Przekazywanie argumentów wskaźniki

Assembler w C++ Syntaksa AT&T oraz Intela

Podstawy programowania. Wykład 6 Wskaźniki. Krzysztof Banaś Podstawy programowania 1

Pytania sprawdzające wiedzę z programowania C++

Podstawy programowania. Wykład Funkcje. Krzysztof Banaś Podstawy programowania 1

Wstęp do programowania

Funkcje. Spotkanie 5. Tworzenie i używanie funkcji. Przekazywanie argumentów do funkcji. Domyślne wartości argumentów

PMiK Programowanie Mikrokontrolera 8051

Wstęp do programowania. Wykład 1

Podstawy Informatyki. Inżynieria Ciepła, I rok. Wykład 10 Kurs C++

Podstawy informatyki (3)

Programowanie w języku C++

Podstawowe elementy proceduralne w C++ Program i wyjście. Zmienne i arytmetyka. Wskaźniki i tablice. Testy i pętle. Funkcje.

Programowanie w C++ Wykład 3. Katarzyna Grzelak. 12 marca K.Grzelak (Wykład 1) Programowanie w C++ 1 / 35

Programowanie w C++ Wykład 1. Katarzyna Grzelak. 25 luty K.Grzelak (Wykład 1) Programowanie w C++ 1 / 38

Wiadomości wstępne Środowisko programistyczne Najważniejsze różnice C/C++ vs Java

Ćwiczenie 3. Konwersja liczb binarnych

ZASADY PROGRAMOWANIA KOMPUTERÓW

Zadanie Zaobserwuj zachowanie procesora i stosu podczas wykonywania następujących programów

Informatyka I. Klasy i obiekty. Podstawy programowania obiektowego. dr inż. Andrzej Czerepicki. Politechnika Warszawska Wydział Transportu 2018

Podstawy programowania. Wykład: 7. Funkcje Przekazywanie argumentów do funkcji. dr Artur Bartoszewski -Podstawy programowania, sem 1 - WYKŁAD

Typy złożone. Struktury, pola bitowe i unie. Programowanie Proceduralne 1

#include <iostream> using namespace std; void ela(int); int main( ); { Funkcja 3. return 0; }

JĘZYKI PROGRAMOWANIA Z PROGRAMOWANIEM OBIEKTOWYM. Wykład 5

Wykład II Tablice (wstęp) Przykłady algorytmów Wstęp do języka C/C++

JĘZYKI PROGRAMOWANIA Z PROGRAMOWANIEM OBIEKTOWYM. Wykład 6

Podstawy programowania w C++

Język C++ zajęcia nr 2

Wykład 3 Składnia języka C# (cz. 2)

Programowanie w C++ Wykład 2. Katarzyna Grzelak. 4 marca K.Grzelak (Wykład 1) Programowanie w C++ 1 / 44

Microsoft IT Academy kurs programowania

Struktury Struktura polami struct struct struct struct

Wykład I. Programowanie II - semestr II Kierunek Informatyka. dr inż. Janusz Słupik. Wydział Matematyki Stosowanej Politechniki Śląskiej

Podstawy Programowania

Rodzina protokołów TCP/IP. Aplikacja: ipconfig.

Technologie cyfrowe semestr letni 2018/2019

PROGRAMOWANIE NISKOPOZIOMOWE

Temat 1: Podstawowe pojęcia: program, kompilacja, kod

petla:... ; etykieta określa adres w pamięci kodu (docelowe miejsce skoku) DJNZ R7, petla

Języki i metodyka programowania. Wprowadzenie do języka C

Kurs programowania. Wykład 1. Wojciech Macyna. 3 marca 2016

Wstęp do informatyki- wykład 11 Funkcje

Podstawy języka skryptowego Lua

Wstęp do informatyki- wykład 9 Funkcje

Tablice (jedno i wielowymiarowe), łańcuchy znaków

Laboratorium 1. Programowanie II - Kierunek Informatyka. dr inż. Janusz Słupik. Gliwice, Wydział Matematyki Stosowanej Politechniki Śląskiej

Instrukcja do ćwiczeń nr 4 typy i rodzaje zmiennych w języku C dla AVR, oraz ich deklarowanie, oraz podstawowe operatory

Wyrażenie include(sciezka_do_pliku) pozwala na załadowanie (wnętrza) pliku do skryptu php. Plik ten może zawierać wszystko, co może się znaleźć w

Programowanie. programowania. Klasa 3 Lekcja 9 PASCAL & C++

Programowanie strukturalne i obiektowe. Funkcje

002 Opcode Strony projektu:

Język C zajęcia nr 11. Funkcje

Obsługa wyjątków. Język C++ WW12

Programowanie Strukturalne i Obiektowe Słownik podstawowych pojęć 1 z 5 Opracował Jan T. Biernat

Wyjątki (exceptions)

Metody Realizacji Języków Programowania

PROGRAMY REZYDENTNE Terminate and State Resident, TSR

20. Pascal i łączenie podprogramów Pascala z programem napisanym w C

Wstęp do informatyki- wykład 12 Funkcje (przekazywanie parametrów przez wartość i zmienną)

Co to jest sterta? Sterta (ang. heap) to obszar pamięci udostępniany przez system operacyjny wszystkim działającym programom (procesom).

Programowanie C++ Wykład 2 - podstawy języka C++ dr inż. Jakub Możaryn. Warszawa, Instytut Automatyki i Robotyki

Programowanie na poziomie sprzętu. Programowanie w Windows API

Przeciążanie operatorów

Dariusz Brzeziński. Politechnika Poznańska, Instytut Informatyki

Mechanizm dziedziczenia

Programowanie w C++ Wykład 5. Katarzyna Grzelak. 16 kwietnia K.Grzelak (Wykład 1) Programowanie w C++ 1 / 27

Transkrypt:

Programowanie hybrydowe łączenie C/C++ z asemblerem

Konwencje Wywoływanie procedur asemblerowych w kodzie języka wysokiego poziomu wymaga: Ustalenia konwencji nazewniczej używanej w języku programowania i stwierdzenia, czy uwzględnia ona reguły związane z nazewnictwem zmiennych i procedur (np. czy asembler lub kompilator nie zmieniają nazw identyfikatorów w pliku.obj, a jeśli tak to w jaki sposób?) Stosowania nazw segmentów kompatybilnych z nazwami używanymi przez język wysokiego poziomu Pamiętania, że użyty w programie model pamięci (tiny, small, compact, medium, large, huge lub flat) decyduje o rozmiarze segmentu (16 lub 32 bity) i rodzaju odwołań (bliskie wewnątrz tego samego segmentu; dalekie pomiędzy segmentami)

Konwencja wywoływania procedur Dotyczy niskopoziomowych aspektów wywoływania procedur i wymaga określenia: Rejestrów, które należy zachować przy wywołaniu procedury Sposobu przekazywania argumentów do procedury: W rejestrach Na stosie Przez współdzieloną pamięć Inną metodą Porządku przekazywania argumentów do procedury Czy argumenty są przekazywane przez rejestry, czy przez referencję W jaki sposób odtwarzana jest zawartość wskaźnika stosu po powrocie z procedury Sposobu zwracania wyników do wywołującego programu

Konwencje nazewnicze i zewnętrzne identyfikatory Wywoływanie procedur języka asemblerowego z programu napisanego w języku wysokiego poziomu wymaga zgodności nazewniczej identyfikatorów zewnętrznych (nazwy, które są umieszczane w pliku.obj w taki sposób, że linker może udostępnić je innym modułom programu) linker rozpoznaje odwołania do identyfikatorów zewnętrznych, ale tylko wtedy, gdy używane konwencje nazewnicze są spójne Przykład: Program w języku C (np. main.c) wywołuje zewnętrzną procedurę nazywaną ArraySum, kompilator zachowuje wielkość liter i automatycznie dodaje podkreślenie na początku nazwy tj. w tym przypadku zmienia ją na _ArraySum Napisany w języku asemblerowym moduł Array.asm eksportuje nazwę procedury ArraySum jako ARRAYSUM, ponieważ w module Array.asm zastosowano dyrektywę.model określającą opcję języka Pascal Efekt: linker zwraca błąd powód: różnice wyeksportowanych nazw Starsze języki programowania, jak Cobol czy Pascal konwertują identyfikatory do wielkich liter; nowsze języki (np. C, C++, Java) zachowują wielkość liter w identyfikatorach; języki, w których można przeciążać funkcje (np. C++) stosują technikę zwaną dekorowaniem nazw dodającą dodatkowe znaki do nazw funkcji (np. Funkcja MyFunction(int a, double b) może zostać wyeksportowana jako MyFunction#int#double.

Nazwy segmentów Linkując procedurę napisaną w języku asemblerowym z programem napisanym w języku wysokiego poziomu nazwy segmentów muszą być zgodne Stosowanie uproszczonych dyrektyw segmentowych.code,.stack i.data pozwala zachować kompatybilność z nazwami segmentów generowanymi przez kompilator Microsoft C/C++

Modele pamięci Zarówno program, jak i wywoływana procedura zewnętrzna muszą używać tego samego modelu pamięci W trybie rzeczywistym do wyboru są następujące modele small, medium, compact, large oraz huge W trybie chronionym dostępny jest jedynie model flat

Dyrektywa.MODEL W trybach 16 i 32-bitowych MASM stosuje dyrektywę.model by określić m.in.: model pamięci, schemat nazywania procedur, konwencję przekazywania argumentów do procedury Składnia:.MODEL model_pamięci [,opcje]

Model pamięci W 16-bitowym trybie rzeczywistym Tiny pojedynczy segment zawierający kod i dane (pliki.com) Small pojedynczy segment danych i pojedynczy segment kodu, domyślnie cały kod i dane są bliskie Medium wiele segmentów kodu i pojedynczy segment danych Compact pojedynczy segment kodu i wiele segmentów danych Large wiele segmentów danych i kodu Huge tak samo jak large, ale pojedyncze dane mogą rozmiarem przekraczać rozmiar segmentu W 32-bitowym trybie chronionym Flat - 32-bitowe przesunięcie (offset) dla kodu i danych wszystkie dane i kod (łącznie z zasobami systemowymi) w pojedynczym 32-bitowym segmencie (rozmiar do 4 GB)

Opcje modelu Drugi (opcjonalny) parametr dyrektywy.model może zawierać: Informację o stosowanej konwencji wywołania procedur i konwencji nazewniczej dla procedur i symboli publicznych wg języka wysokiego poziomu (np. C, BASIC, FORTRAN, COBOL, PASCAL, STDCALL) Odległość odwołań do stosu: NEARSTACK domyślna FARSTACK

STDCALL Używany przy wywoływaniu funkcji systemowych MS Windows Przekazywanie argumentów odbywa się przez stos w odwróconym porządku np. dla wywołania funkcji Dodaj(5,6) wygenerowany zostanie kod: push 6 push 5 call Dodaj powrót z procedury wymaga zdjęcia ze stosu również argumentów dlatego na końcu procedury musi być instrukcja RET z operandem określającym liczbę bajtów zajmowanych przez argumenty procedury np. RET 8 Eksportowana na zewnątrz (do pliku.obj) nazwa procedury jest modyfikowana do: _nazwa@nn (np. _Dodaj@8) nn określa liczbę bajtów używaną przez argumenty procedury (zaokrągloną w górę do wielokrotności 4) linker rozróżnia wielkość liter w nazwach aby obejrzeć nazwy wszystkich procedur z pliku *.OBJ należy użyć narzędzia DUMPBIN z opcją /SYMBOLS

C Używany w językach C/C++ Wywołanie procedury tak samo jak w STDCALL (argumenty w odwrotnej kolejności na stosie) Zdejmowanie argumentów ze stosu po zakończeniu procedury leży po stronie programisty dla procedury Dodaj (5,6) czyszczenie stosu z argumentów wymaga zastosowania instrukcji add esp,8 Eksportowana nazwa procedury to _nazwa (np. _Dodaj)

Kontrola wygenerowanego kodu Opcje kompilatora związane z generowaniem kodu asemblerowego: z poziomu linii poleceń: /FA wyłącznie plik z kodem asemblera /FAc kod asemblera + kod maszynowy /FAs kod asemblera + kod źródłowy /FAcs kod asemblera + kod maszynowy + kod źródłowy z poziomu środowiska Visual Studio Tools Options Debugging General Enable address-level debugging Assembler Output = (np. Assembly With Source Code) Favour Size Or Speed = (np. Favour fast code) optymalizacja prędkości Optimization = Disabled ze względu na zastosowanie debugera (kod zoptymalizowany jest mniej czytelny dla użytkownika)

Linkowanie 32-bitowego kodu w asemblerze z kodem w C/C++ Asembler: W kodzie źródłowym asemblera należy określić model FLAT, C oraz zdefiniować prototyp dla każdej procedury wywoływanej później z poziomu programu w C/C++ Prototyp dla przykładowej funkcji IndexOf z trzema argumentami (srchval, arrayptr, count) która w tablicy zawierającej count elementów (32-bitowe wartości) wyszukuje pierwszego elementu o wartości równej srchval i zwraca indeks tej komórki jako arrayptr (lub -1, gdy element taki w tablicy nie występuje) IndexOf PROTO, srchval:dword, arrayptr:ptr DWORD, count:dword

Linkowanie 32-bitowego kodu w asemblerze z kodem w C/C++ C: zewnętrzną funkcję należy zadeklarować jako extern extern long IndexOf( long n, long array[], unsigned count ); C++: zadeklarować zewnętrzną funkcję jako extern i wymusić stosowanie konwencji nazewniczej języka C (C++ ze względu na możliwość przecążania funkcji stosuje dekorowanie nazw) extern C int IndexOf( long n, long array[], unsigned count );

Przykład moduł asm dla IndexOf.586.model flat,c IndexOf PROTO, srchval:dword, arrayptr:ptr DWORD, count:dword.code IndexOf PROC USES ecx esi edi,srchval:dword, arrayptr:ptr DWORD, count:dword NOT_FOUND = -1 mov eax,srchval mov ecx,count mov esi,arrayptr mov edi,0 L1: cmp [esi+edi*4],eax je found inc edi loop L1 notfound: mov al,not_found jmp short exit found: exit: IndexOf mov eax,edi ret ENDP END

Program w C++ z procedurą IndexOf #include <iostream> #include <time.h> #include "indexof.h" using namespace std; int main() { // Fill an array with pseudorandom integers. const unsigned ARRAY_SIZE = 100000; const unsigned LOOP_SIZE = 100000; char* boolstr[] = {"false","true"}; long array[array_size]; for(unsigned i = 0; i < ARRAY_SIZE; i++) array[i] = rand(); long searchval; time_t starttime, endtime; cout << "Enter an integer value to find: "; cin >> searchval; cout << "Please wait...\n"; // Test the Assembly language function. time( &starttime ); int count = 0; for( unsigned n = 0; n < LOOP_SIZE; n++) count = IndexOf( searchval, array, ARRAY_SIZE ); bool found = count!= -1; time( &endtime ); cout << "Elapsed ASM time: " << long(endtime - starttime) << " seconds. Found = " << boolstr[found] << endl; } return 0;

Wywoływanie funkcji C/C++ Funkcje języka C/C++ można wywoływać z poziomu języka asemblerowego Szczególnie przydatne gdy: Programista chce skorzystać z funkcji we/wy Programista chce skorzystać z funkcji matematycznych np. liczenie pierwiastków Wywoływanie funkcji C/C++ wymaga uruchomienia programu z funkcji main() w celu prawidłowego zainicjowania kodu bibliotecznego

Prototypy funkcji Wywoływanie funkcji C++ z poziomu języka asemblerowego wymaga definicji z opcją C oraz extern Składnia extern C nazwafunkcji (lista_parametrów) { } Przykład: extern C int wczytajliczbę () { cout << Podaj liczbę z zakresu 1..100: ; // } Zamiast zmieniać definicje wszystkich funkcji wywoływanych z poziomu języka asemblerowego można ująć w jednym bloku extern C prototypy tych funkcji Przykład: extern C { } int wczytajliczbę (); int dodajint(int a,int b); //

Moduł asemblerowy Dyrektywa.model flat, STDCALL umożliwia wywoływanie procedur WIn32 API, ale nie jest kompatybilna z mechanizmem wywoływania funkcji języka C/C++ Deklarowanie zewnętrznych funkcji języka C/C++ wewnątrz takiego programu asemblerowego wymaga zastosowania kwalifikatora C z dyrektywą PROTO Przykład: INCLUDE biblioteka.inc wczytajliczbę PROTO C dodajint PROTO C, a: SDWORD, b:sdword

Moduł asemblerowy cd. Procedury asemblerowe wywoływane z poziomu języka C/C++ również muszą używać kwalifikatora C Przykład: SetTextOutColor PROC C, color: DWORD SetTextOutColor ENDP Jeśli moduł asemblerowy korzysta z procedur asemblerowych z innych modułów, to korzystanie z konwencji C wymaga po każdym wywołaniu procedury usuwania parametrów ze stosu

Wartości zwracane przez funkcję języka C/C++ Sposób zwracania wartości nie jest określony w specyfikacji języka C/C++ Należy sprawdzić w dokumentacji kompilatora W MS Visual C++: bool i char w AL. short int w AX int i long int w EAX wskaźniki w EAX float, double, long double odkładane na stosie zmiennopozycyjnym jako 4, 8 lub 10 bajtowe wartości