Programowanie niskopoziomowe dr inż. Paweł Pełczyński ppelczynski@swspiz.pl 1
Literatura Randall Hyde: Asembler. Sztuka programowania, Helion, 2004. Eugeniusz Wróbel: Praktyczny kurs asemblera, Helion, 2004. W prezentacji wykorzystano zdjęcia ze stron: http://pl.wikipedia.org http://www.dis.uniroma1.it/~iocchi/stereo/ 2
Cechy programowania niskopoziomowego Programowanie niskopoziomowe wymaga od programisty znajomości sprzętu, w szczególności architektury mikroprocesora. Programy są pisane w języku pozwalającym na bezpośrednie odwołania do rejestrów mikroprocesora, portów I/O i pamięci systemu zazwyczaj jest to asembler. Programowanie w języku niskiego poziomu wymaga doświadczenia, jest czasochłonne i narażone na błędy. 3
Uzasadnienie potrzeby programowania niskopoziomowego Programowanie niskopoziomowe pozwala na najdalej idącą optymalizację kodu pod względem szybkości wykonania lub objętości programu. 4
Zastosowania programowania niskopoziomowego Tworzenie sterowników i programów startowych Pisanie elementów jądra systemu operacyjnego Pisanie programów dla mikrokontrolerów o bardzo ograniczonych zasobach Tworzenie silnie zoptymalizowanych aplikacji dla tzw. systemów wbudowanych Realizacja wydajnych aplikacji dla systemów przetwarzania sygnałów i obrazów (DSP) Programowanie procesorów wektorowych, np. GPU 5
Zastosowania programowania niskopoziomowego Tworzenie sterowników i programów startowych Przykładem takiego oprogramowania jest system BIOS umieszczony w pamięci nieulotnej płyty głównej komputera PC. Jego zadaniem jest: konfiguracja i inicjalizacja pracy układów wchodzących w skład systemu załadowanie do pamięci i uruchomienie programu ładującego system operacyjny utworzenie programowej abstrakcji sprzętu, pozwalającej na ujednolicone odwołania aplikacji programowych do urządzeń, niezależnie od ich budowy (funkcje i przerwania BIOSu) 6
Zastosowania programowania niskopoziomowego Pisanie programów dla mikrokontrolerów o bardzo ograniczonych zasobach Mikrokontrolery są jednoukładowymi komputerami, często stosowanymi do sterowania sprzętem elektronicznym powszechnego użytku. Ze względu na wymaganie małego kosztu ich zasoby są silnie ograniczone, co wymaga tworzenia wysoce zoptymalizowanych aplikacji programowych. Wysoki koszt tworzenia aplikacji w języku niskopoziomowym jest uzasadniony produkcją wielkoseryjną sprzętu. 7
Zastosowania programowania niskopoziomowego Tworzenie silnie zoptymalizowanych aplikacji dla tzw. systemów wbudowanych Podobnie, jak poprzednio, wysoki koszt tworzenia aplikacji w języku niskopoziomowym jest uzasadniony produkcją wielkoseryjną sprzętu. 8
Zastosowania programowania niskopoziomowego Realizacja wydajnych aplikacji dla systemów przetwarzania sygnałów i obrazów (DSP) Niektóre aplikacje wymagają dużej mocy obliczeniowej, by mogły realizować postawione zadania w czasie rzeczywistym. Osiąga się to przez zastosowanie specjalizowanych procesorów sygnałowych (DSP) oprogramowanych w asemblerze. 9
Zastosowania programowania niskopoziomowego Programowanie procesorów wektorowych, np. GPU Programowanie procesorów wektorowych, np. procesorów graficznych, wymaga specyficznego podejścia, ze względu ma możliwość przetwarzania wielu danych w jednej instrukcji. W tym celu zostały opracowane specjalizowane języki niskiego poziomu. 10
Języki programowania niskopoziomowego Pierwsza generacja - Język wewnętrzny (maszynowy). Druga generacja - Język symboliczny (asembler). Języki symboliczne wysokiego poziomu pozwalające na operowanie na fizycznych rejestrach, portach i pamięci komputera, posiadają cechy języków niskiego poziomu pozwalają na tworzenie programów o podobnej funkcjonalności. 11
Język wewnętrzny Język wewnętrzny (maszynowy) jest definiowany operacjami realizowanymi przez mikroprocesor Lista instrukcji jest zbiorem wszystkich operacji wykonywanych przez mikroprocesor Odpowiednio uporządkowany ciąg instrukcji stanowi program kod maszynowy 12
Język wewnętrzny - wady Reprezentacja instrukcji za pomocą kodów liczbowych Trudne tworzenie i poprawianie programu Wymagana jest dobra znajomość danej platformy sprzętowej 13
Język symboliczny - asembler Asemblery są językami powstałymi na bazie języka maszynowego danego mikroprocesora przez zastąpienie kodów instrukcji nazwami symbolicznymi mnemonikami Asembler jest językiem niskiego poziomu, jedno polecenie asemblera odpowiada zazwyczaj jednemu rozkazowi mikroprocesora 14
Asembler - cechy Mnemoniczne nazwy operacji Operowanie symbolicznymi nazwami adresów danych i etykiet Możliwość stosowania makrooperacji Możliwość łatwiejszego modyfikowania programu 15
Asembler składnia linii programu [etykieta:] [instrukcja [argument1 [, argument2...]]][; komentarz] Etykieta jest symboliczną nazwą adresu instrukcji Przykład: laduj: mov ax, $20A4 ; załaduj do rejestru ax daną szesnastkową 20A4 Program napisany w języku asemblera wymaga asemblacji przetłumaczenia na kod maszynowy. Program tłumaczący jest także nazywany asemblerem. 16
Asembler makrooperacje Często powtarzający się ciąg instrukcji można zastąpić tzw. makroopperacją Makrooperację definiuje się przez umieszczenie ciągu instrukcji między poleceniami: macro nazwa i endm Przykład: macro mnoz_int x, y mov ax, x ; załaduj do rejestru ax pierwszą daną mov bx, y ; załaduj do rejestru ax drugą daną imul; endm... mnoz_int a, b ; makro użyte w programie... 17
Program tłumaczący - translator Kompilator języka symbolicznego (asemblera) tłumaczy program na kod maszynowy Proces kompilacji jest tutaj nazywany asemblacją, a sam kompilator asemblerem. 18
Cechy Języka C B.Kernighan, D. Ritchie 1971 Język C jest językiem względnie niskopoziomowym wśród języków strukturalnych. Posiada następujące cechy: Nie sprawdza rozmiaru pamięci przydzielonej na tablice Pozwala alokować pamięć, nie podając typu danych w niej przechowywanych Pozwala na manipulację portami komputera na niskim poziomie Ze względu na te cechy został zastosowany do napisania elementów systemu operacyjnego UNIX 19