DZWON

Są tacy, którzy czytają tę wiadomość przed wami.
Zapisz się, aby otrzymywać najnowsze artykuły.
E-mail
Imię
Nazwisko
Jak chcesz przeczytać The Bell
Bez spamu

Temat 1.4 Mnemoniki asemblera. Struktura i formaty poleceń. Rodzaje adresowania. Zestaw poleceń mikroprocesora

Plan:

1 Język asemblera. Podstawowe koncepcje

2 Symbole języka asemblera

3 Rodzaje instrukcji asemblera

4 Dyrektywy montażowe

5 Zestaw instrukcji procesora

1 ijęzyk programowania. Podstawowe koncepcje

język programowania jest symboliczną reprezentacją języka maszynowego. Wszystkie procesy w maszynie na najniższym poziomie sprzętowym są sterowane tylko przez polecenia języka maszynowego (instrukcje). Stąd jasne jest, że pomimo ogólnej nazwy, język asemblera dla każdego typu komputera jest inny.

Program w języku asemblerowym to zbiór bloków pamięci o nazwie segmenty pamięci.Program może składać się z jednego lub więcej takich segmentów bloków. Każdy segment zawiera zestaw zdań językowych, z których każde zajmuje oddzielną linię kodu programu.

Zdania asemblacyjne są czterech typów:

1) polecenia lub instrukcje, które są symbolicznymi odpowiednikami instrukcji maszynowych. W procesie tłumaczenia instrukcje asemblera są konwertowane na odpowiednie polecenia zestawu instrukcji mikroprocesora;

2) makra -zdania z tekstu programu, które są uformowane w określony sposób, które w trakcie emisji są zastępowane innymi zdaniami;

3) dyrektywy,które są instrukcjami dla tłumacza asemblera, aby wykonać pewne czynności. Dyrektywy nie mają odpowiednika w reprezentacji maszyn;

4) linie komentarza zawierające dowolne symbole, w tym litery alfabetu rosyjskiego. Komentarze są ignorowane przez tłumacza.

­ Struktura programu w asemblerze. Składnia zestawu.

Zdania składające się na program mogą być konstrukcją składniową odpowiadającą poleceniu, makrowi, dyrektywie lub komentarzowi. Aby tłumacz asemblera mógł je rozpoznać, muszą być utworzone zgodnie z określonymi regułami składniowymi. Najlepszym sposobem na to jest użycie formalnego opisu składni języka, na przykład reguł gramatycznych. Najczęstsze sposoby opisania takiego języka programowania - diagramy składniowe i rozszerzone formy Backus-Naur. Bardziej wygodny w praktycznym użyciu diagramy składniowe.Na przykład składnię zdań asemblera można opisać za pomocą diagramów składni przedstawionych na poniższych rysunkach 10, 11, 12.

Rysunek 10 - Format zdania zestawu


­ Rysunek 11 - Format dyrektyw

­ Rysunek 12 - Format poleceń i makr

Na tych liczbach:

­ nazwa etykiety - identyfikator, którego wartością jest adres pierwszego bajtu zdania tekstu źródłowego programu, który oznacza;

­ imię - identyfikator, który odróżnia tę dyrektywę od innych dyrektyw o tej samej nazwie. W wyniku przetwarzania w języku asemblerowym określonej dyrektywy, tej nazwie można przypisać pewne cechy;

­ kod operacji (COP) i dyrektywa - są to oznaczenia mnemoniczne odpowiednich instrukcji maszynowych, makr lub dyrektyw translatora;

­ operandy - części polecenia, makra lub dyrektywy assemblera, które wyznaczają obiekty do manipulacji. Operandy asemblera są opisywane wyrażeniami zawierającymi stałe numeryczne i tekstowe, etykiety i identyfikatory zmiennych przy użyciu znaków operacji i niektórych słów zastrzeżonych.

Diagramy składniowe - pomoc znajdź, a następnie przejdź od wejścia diagramu (po lewej) do jego wyjścia (po prawej). Jeśli taka ścieżka istnieje, to zdanie lub konstrukcja jest poprawna składniowo. Jeśli nie ma takiej ścieżki, kompilator nie zaakceptuje tej konstrukcji.

­ 2 Symbole języka asemblera

Dozwolone znaki podczas pisania tekstu programu to:

1) wszystkie litery łacińskie: A-Z, a-z... W takim przypadku wielkie i małe litery są uważane za równoważne;

2) numery od 0 przed 9 ;

3) znaki ? , @ , $ , _ , & ;

4) separatory , . () < > { } + / * % ! " " ? = # ^ .

Zdania asemblera są tworzone z tokeny, które są składniowo nierozłącznymi sekwencjami prawidłowych znaków językowych, które mają sens dla tłumacza.

Lexemes są:

1) identyfikatory - sekwencje prawidłowych znaków używanych do oznaczania obiektów programu, takich jak kody operacyjne, nazwy zmiennych i nazwy etykiet. Zasada zapisywania identyfikatorów jest następująca: identyfikator może składać się z jednego lub więcej znaków;

2) ciągi znaków - sekwencje znaków ujęte w pojedyncze lub podwójne cudzysłowy;

3) liczby całkowite jednego z następujących systemów liczbowych : binarny, dziesiętny, szesnastkowy. Identyfikacja numerów podczas pisania ich w programach asemblerowych odbywa się według pewnych zasad:

4) liczby dziesiętne nie wymagają dodatkowych symboli do ich identyfikacji, na przykład 25 lub 139. Do identyfikacji w kodzie źródłowym programu liczby binarne po zapisaniu zer i jedynek, które je tworzą, należy umieścić łaciński „ b”, Na przykład 10010101 b.

5) liczby szesnastkowe mają więcej konwencji, gdy są zapisywane:

Po pierwsze, składają się z liczb 0...9 , małe i wielkie litery alfabetu łacińskiego za, b, do, re, mi, fa lub ZA, b, do, re, mi, fa.

Po drugie, tłumacz może mieć trudności z rozpoznaniem liczb szesnastkowych ze względu na fakt, że mogą one składać się albo z samych cyfr 0 ... 9 (np. 190845), albo zaczynać się od litery alfabetu łacińskiego (np. ef15). Aby „wyjaśnić” tłumaczowi, że dany token nie jest liczbą dziesiętną ani identyfikatorem, programista musi w specjalny sposób wybrać liczbę szesnastkową. Aby to zrobić, na końcu sekwencji cyfr szesnastkowych, które tworzą liczbę szesnastkową, wpisz łacińską literę „ godz”. To warunek wstępny. Jeśli liczba szesnastkowa zaczyna się od litery, to przed nią wpisywane jest zero: 0 ef15 godz.

Niemal każde zdanie zawiera opis przedmiotu, na którym lub za pomocą którego jest wykonywana jakaś akcja. Te obiekty są nazywane operandy... Można je zdefiniować w następujący sposób: operandy są obiektami (pewnymi wartościami, rejestrami lub komórkami pamięci), na które oddziałują instrukcje lub dyrektywy, lub też są obiektami, które definiują lub określają działanie instrukcji lub dyrektyw.

Możliwe jest przeprowadzenie następującej klasyfikacji operandów:

­ operandy stałe lub natychmiastowe;

­ argumenty adresu;

­ ruchome operandy;

licznik adresów;

­ zarejestruj operand;

­ operandy bazowe i indeksowe;

­ operandy strukturalne;

dokumentacja.

Argumenty to elementarne komponenty, które tworzą część instrukcji maszynowej, która oznacza obiekty, na których wykonywana jest operacja. W bardziej ogólnym przypadku operandy mogą być dołączane jako części składowe w bardziej złożonych formacjach, tzw wyrażenia.

Wyrażenia to kombinacje operandów i operatorów, rozpatrywane jako całość. Wynikiem oceny wyrażenia może być adres określonej komórki pamięci lub pewna stała (bezwzględna) wartość.

­ 3 Rodzaje instrukcji asemblera

Wymieńmy możliwe typy operatorzy asemblerów i reguły składniowe tworzenia wyrażeń asemblera:

­ operatory arytmetyczne;

­ operatorzy zmianowi;

­ operatory porównania;

­ operatory logiczne;

­ operator indeksu;

­ operator przesłonięcia typu;

­ operator redefinicji segmentu;

­ operator nazewnictwa typu struktury;

­ operator do uzyskiwania składnika segmentu adresu wyrażenia;

­ operator, aby uzyskać przesunięcie wyrażenia.

1 Dyrektywy asemblera

­ Dyrektywy asemblera to:

1) Dyrektywy dotyczące segmentacji. W trakcie poprzedniej dyskusji poznaliśmy wszystkie podstawowe zasady pisania poleceń i operandów w programie asemblera. Otwarta pozostaje kwestia prawidłowego sformułowania sekwencji poleceń, aby tłumacz mógł je przetworzyć, a mikroprocesor mógł je wykonać.

Rozważając architekturę mikroprocesora dowiedzieliśmy się, że posiada on sześć rejestrów segmentowych, dzięki którym może pracować jednocześnie:

­ z jednym segmentem kodowym;

­ z jednym segmentem stosu;

­ z jednym segmentem danych;

­ z trzema dodatkowymi segmentami danych.

Fizycznie segment jest obszarem pamięci zajmowanym przez instrukcje i (lub) dane, których adresy są obliczane w stosunku do wartości w odpowiednim rejestrze segmentu. Opis składniowy segmentu w asemblerze to konstrukcja pokazana na rysunku 13:


­ Rysunek 13 - Syntaktyczny opis segmentu w asemblerze

Należy zauważyć, że funkcjonalność segmentu jest nieco szersza niż zwykłe dzielenie programu na bloki kodu, danych i stosu. Segmentacja jest częścią bardziej ogólnego mechanizmu związanego z koncepcja programowania modułowego. Polega ona na ujednoliceniu projektowania modułów obiektowych tworzonych przez kompilator, w tym z różnych języków programowania. Pozwala to łączyć programy napisane w różnych językach. Operandy w dyrektywie SEGMENT mają za zadanie implementację różnych wariantów takiej unii.

2) Dyrektywy zarządzania ofertami. Dyrektywy kontroli list są podzielone na następujące grupy:

­ ogólne dyrektywy dotyczące zarządzania wykazami;

­ dyrektywy wyjściowe do listy załączonych plików;

­ dyrektywy do wyprowadzania warunkowych bloków montażowych;

­ dyrektywy dotyczące wyświetlania makr;

­ dyrektywy dotyczące wyprowadzania informacji o odsyłaczach do wykazu;

­ dyrektywy dotyczące zmiany formatu listy.

2 Zestaw instrukcji procesora

Zestaw instrukcji procesora pokazano na rysunku 14.

Rozważmy główne grupy zespołów.

­ Rysunek 14 - Klasyfikacja instrukcji asemblera

Zespoły to:

1 Polecenia przesyłania danych. Te polecenia zajmują bardzo ważne miejsce w zestawie instrukcji dowolnego procesora. Pełnią następujące podstawowe funkcje:

­ przechowywanie w pamięci zawartości wewnętrznych rejestrów procesora;

­ kopiowanie treści z jednego obszaru pamięci do drugiego;

­ zapis do urządzeń I / O i odczyt z urządzeń I / O.

Na niektórych procesorach wszystkie te funkcje są wykonywane za pomocą jednego poleceniaMOV (dla transferów bajtowych -MOVB ) ale z różnymi metodami adresowania argumentów.

Na innych procesorach oprócz poleceniaMOV jest jeszcze kilka poleceń do wykonania wymienionych funkcji. Ponadto polecenia przesyłania danych obejmują polecenia wymiany informacji (ich oznaczenie jest oparte na słowieWymieniać się ). Wymiana informacji między rejestrami wewnętrznymi, między dwiema połówkami jednego rejestru (ZAMIANA ) lub między rejestrem a miejscem w pamięci.

2 Polecenia arytmetyczne. Instrukcje arytmetyczne traktują kody operandów jako numeryczne kody binarne lub binarno-dziesiętne. Polecenia te można podzielić na pięć głównych grup:

­ polecenia operacji na punktach stałych (dodawanie, odejmowanie, mnożenie, dzielenie);

­ polecenia zmiennoprzecinkowe (dodawanie, odejmowanie, mnożenie, dzielenie);

­ polecenia czyszczenia;

­ polecenia zwiększania i zmniejszania;

­ polecenie porównania.

3 Polecenia operacji ze stałym punktem działają z kodami w rejestrach procesora lub w pamięci jak w przypadku zwykłych kodów binarnych. Instrukcje zmiennoprzecinkowe (punktowe) używają formatu przedstawiania liczb z porządkiem i mantysą (zwykle te liczby zajmują dwa kolejne miejsca w pamięci). W nowoczesnych potężnych procesorach zestaw instrukcji zmiennoprzecinkowych nie ogranicza się tylko do czterech operacji arytmetycznych, ale zawiera również wiele innych bardziej złożonych instrukcji, na przykład obliczanie funkcji trygonometrycznych, funkcji logarytmicznych, a także złożonych funkcji niezbędnych do przetwarzania dźwięku i obrazu.

4 Instrukcje kasowania mają na celu zapisanie kodu zerowego do rejestru lub komórki pamięci. Te polecenia można zastąpić zerowymi poleceniami przesyłania, ale specjalne jasne polecenia są zwykle szybsze niż polecenia przesyłania.

5 Polecenia zwiększania (zwiększania o jeden) i zmniejszania

(zmniejszenie o jeden) są również bardzo wygodne. Zasadniczo można je zastąpić dodawaniem jednym poleceniem lub odejmowaniem jednego polecenia, ale zwiększanie i zmniejszanie jest szybsze niż dodawanie i odejmowanie. Te instrukcje wymagają jednego operandu wejściowego, który jest również operandem wyjściowym.

6 Instrukcja porównania porównuje dwa operandy wejściowe. W rzeczywistości oblicza różnicę między tymi dwoma operandami, ale nie tworzy argumentu wyjściowego, a jedynie zmienia bity w rejestrze stanu procesora w wyniku tego odejmowania. Następna instrukcja następująca po instrukcji porównania (zwykle jest to instrukcja rozgałęzienia) przeanalizuje bity w rejestrze stanu procesora i wykona działania w zależności od ich wartości. Niektóre procesory udostępniają instrukcje dotyczące łączenia łańcuchowego dwóch sekwencji operandów w pamięci.

7 Polecenia logiczne. Instrukcje logiczne wykonują operacje logiczne (bitowe) na operandach, to znaczy traktują kody operandów nie jako pojedynczą liczbę, ale jako zestaw oddzielnych bitów. Tym się różnią od poleceń arytmetycznych. Polecenia logiczne wykonują następujące podstawowe operacje:

­ logiczne AND, logiczne OR, dodawanie modulo 2 (wyłączne OR);

­ przesunięcia logiczne, arytmetyczne i cykliczne;

­ sprawdzanie bitów i operandów;

­ ustawianie i kasowanie bitów (flag) rejestru stanu procesora (PSW).

Instrukcje logiczne umożliwiają obliczanie podstawowych funkcji logicznych z dwóch argumentów wejściowych bit po bicie. Ponadto operacja AND jest używana do wymuszonego kasowania określonych bitów (jako jeden z argumentów używany jest kod maski, w którym bity do wyczyszczenia są ustawione na zero). Operacja OR służy do wymuszenia ustawienia określonych bitów (jako jeden z operandów używany jest kod maski, w którym cyfry wymagające ustawienia na jeden są równe jeden). Operacja „Exclusive OR” służy do odwracania określonych bitów (kod maski jest używany jako jeden z operandów, w którym bity do odwrócenia są ustawione na jeden). Instrukcje wymagają dwóch operandów wejściowych i tworzą jeden operand wyjściowy.

8 poleceń Shift pozwala przesuwać kod argumentu bit po bicie w prawo (w kierunku bitów o najniższej kolejności) lub w lewo (w kierunku bitów o najwyższym porządku). Rodzaj przesunięcia (logiczne, arytmetyczne lub cykliczne) określa, jaka będzie nowa wartość najbardziej znaczącego bitu (przy przesuwaniu w prawo) lub najmniej znaczącego bitu (przy przesuwaniu w lewo), a także określa, czy zostanie gdzieś zapisana poprzednia wartość najbardziej znaczącego bitu (przy przesuwaniu w lewo) lub najmniej znaczący bit (po przesunięciu w prawo). Przesunięcia cykliczne pozwalają na przesuwanie bitów operandu w sposób okrężny (zgodnie z ruchem wskazówek zegara po przesunięciu w prawo lub przeciwnie do ruchu wskazówek zegara po przesunięciu w lewo). W takim przypadku flaga nośna może, ale nie musi być umieszczona w pierścieniu przełączającym. Bit flagi przeniesienia (jeśli jest używany) przechowuje wartość najbardziej znaczącego bitu, gdy jest cyklicznie w lewo i najmniej znaczącego bitu, gdy jest cyklicznie w prawo. Odpowiednio, wartość bitu flagi przeniesienia zostanie nadpisana w najmniej znaczącym bicie podczas przełączania w lewo i w najbardziej znaczącym bicie podczas jazdy w prawo.

9 Polecenia przejść. Instrukcje skoku są przeznaczone do organizowania wszelkiego rodzaju pętli, rozgałęzień, wywołań podprogramów itp., To znaczy zakłócają sekwencyjny przepływ programu. Polecenia te zapisują nową wartość w rejestrze licznika poleceń i powodują, że procesor nie przechodzi do następnego polecenia w kolejności, ale do dowolnego innego polecenia w pamięci programu. Niektóre polecenia przejścia zapewniają dalszy powrót do punktu, z którego nastąpiło przejście, inne tego nie przewidują. Jeśli podano zwrot, to bieżące parametry procesora są przechowywane na stosie. Jeśli nie zostanie podany żaden zwrot, bieżące parametry procesora nie zostaną zapisane.

Polecenia przejścia bez cofania są podzielone na dwie grupy:

­ bezwarunkowe polecenia skoku;

­ warunkowe polecenia skoku.

Te polecenia używają słówBranch (branch) i Jump (jump).

Bezwarunkowe instrukcje skoku powodują skok do nowego adresu niezależnie od wszystkiego. Mogą powodować skok o określoną wielkość przesunięcia (do przodu lub do tyłu) lub do określonego adresu pamięci. Wartość przesunięcia lub nowa wartość adresu jest określona jako operand wejściowy.

Warunkowe instrukcje skoku nie zawsze powodują skok, ale tylko wtedy, gdy spełnione są określone warunki. Te warunki są zwykle wartościami flag w rejestrze stanu procesora (PSW ). Oznacza to, że warunek przejścia jest wynikiem poprzedniej operacji, która zmienia wartości flag. Takich warunków skoku może być w sumie od 4 do 16. Kilka przykładów warunkowych poleceń skoku:

­ przejście, jeśli jest równe zero;

­ przejście, jeśli nie jest równe zero;

­ przeskocz, jeśli jest przepełnienie;

­ przeskoczyć, jeśli nie ma przepełnienia;

­ przejście, jeśli jest większe niż zero;

­ skok, jeśli jest mniejszy lub równy zero.

Jeśli warunek przejścia jest spełniony, nowa wartość jest ładowana do rejestru poleceń. Jeśli warunek skoku nie jest spełniony, licznik instrukcji jest po prostu zwiększany, a procesor wybiera i wykonuje następną instrukcję w kolejności.

Polecenie porównania (CMP), które poprzedza polecenie warunkowego skoku (lub nawet kilka warunkowych poleceń skoku), jest używane specjalnie do sprawdzania warunków skoku. Ale flagi można ustawić za pomocą dowolnego innego polecenia, na przykład polecenia przesłania danych, dowolnego polecenia arytmetycznego lub logicznego. Zauważ, że same polecenia skoku nie zmieniają flag, co po prostu pozwala ci umieścić kilka poleceń skoku jeden po drugim.

Polecenia przerwań zajmują szczególne miejsce wśród poleceń skoku wstecz. Te instrukcje wymagają numeru przerwania (adresu wektora) jako argumentu wejściowego.

Wynik:

Język asemblera jest symboliczną reprezentacją języka maszynowego. Język asemblera dla każdego typu komputera jest inny. Program w języku asemblerowym to zbiór bloków pamięci zwanych segmentami pamięci. Każdy segment zawiera zestaw zdań językowych, z których każde zajmuje oddzielną linię kodu programu. Istnieją cztery typy zdań asemblerowych: polecenia lub instrukcje, makra, dyrektywy, wiersze komentarzy.

Wszystkie litery łacińskie są prawidłowymi znakami podczas pisania tekstu programu: A-Z, a-z... W takim przypadku wielkie i małe litery są uważane za równoważne; liczby z 0 przed 9 ; oznaki ? , @ , $ , _ , & ; separatory , . () < > { } + / * % ! " " ? = # ^ .

Stosowane są następujące typy instrukcji asemblera i reguły składniowe do tworzenia wyrażeń asemblera. operatory arytmetyczne, operatory przesunięcia, operatory porównania, operatory logiczne, operator indeksu, operator przesłonięcia typu, operator nadpisania segmentu, operator nazewnictwa typu struktury, operator do uzyskiwania składnika segmentu adresu wyrażenia, operator do uzyskiwania przesunięcia wyrażenia.

System dowodzenia podzielony jest na 8 głównych grup.

­ Pytania testowe:

1 Co to jest język asemblera?

2 Jakich symboli można używać do pisania poleceń w języku asemblera?

3 Jakie są etykiety i ich przeznaczenie?

4 Wyjaśnij strukturę poleceń asemblera.

5 Wymień 4 typy zdań asemblera.

Struktury asemblera

Tablice, które rozważaliśmy powyżej, są zbiorem elementów tego samego typu. Ale często w aplikacjach konieczne staje się rozważenie określonego zbioru danych różnych typów jako pewnego jednego typu.

Jest to bardzo ważne na przykład w przypadku programów bazodanowych, w których konieczne jest powiązanie zbioru danych różnych typów z jednym obiektem.

Na przykład, przyjrzeliśmy się wcześniej Listing 4, w którym pracowaliśmy z tablicą elementów trzy-bajtowych. Z kolei każdy element był reprezentowany przez dwa elementy różnego typu: jednobajtowe pole licznika i dwubajtowe pole, które może przenosić inne informacje niezbędne do przechowywania i przetwarzania. Jeśli czytelnik jest zaznajomiony z jednym z języków wysokiego poziomu, to wie, że taki obiekt jest zwykle opisywany za pomocą specjalnego typu danych - struktury.

Aby poprawić użyteczność języka asemblera, wprowadzono do niego również ten typ danych.

A-priory struktura to typ danych składający się z ustalonej liczby elementów różnych typów.

Aby użyć struktur w programie, musisz zrobić trzy rzeczy:

    Zapytać szablon struktury .

    Z definicji oznacza to zdefiniowanie nowego typu danych, którego można później użyć do zdefiniowania zmiennych tego typu.

    Definiować instancja struktury .

    Ten etap polega na inicjalizacji określonej zmiennej z predefiniowaną (przy użyciu szablonu) strukturą.

    Zorganizować dostęp do elementów konstrukcji .

Bardzo ważne jest, aby od początku zrozumieć, jaka jest różnica między nimi opis struktura w programie i jej definiowanie.

Opisać struktura w programie oznacza jedynie wskazanie jego schematu lub szablonu; żadna pamięć nie jest przydzielana.

Ten szablon można traktować jedynie jako informację dla tłumacza o lokalizacji pól i ich wartościach domyślnych.

Definiować struktura oznacza poinstruowanie tłumacza, aby przydzielił pamięć i przypisał symboliczną nazwę temu obszarowi pamięci.

Strukturę w programie można opisać tylko raz i zdefiniować dowolną liczbę razy.

Opis szablonu struktury

Opis szablonu struktury ma następującą składnię:

nazwa_struktury STRUC

nazwa_struktury KONIEC

Tutaj to sekwencja dyrektyw opisujących dane db, dw, dd, dq i dt.

Ich operandy określają rozmiar pól i, jeśli to konieczne, wartości początkowe. Te wartości zostaną prawdopodobnie zainicjowane w odpowiednich polach podczas definiowania struktury.

Jak zauważyliśmy, opisując szablon, nie jest przydzielana żadna pamięć, ponieważ jest to tylko informacja dla tłumacza.

Lokalizacja Szablon w programie może być dowolny, ale zgodnie z logiką translatora jednoprzebiegowego musi znajdować się aż do miejsca, w którym definiowana jest zmienna o typie tej struktury. Oznacza to, że opisując zmienną z typem struktury w segmencie danych, jej szablon należy umieścić na początku segmentu danych lub przed nim.

Rozważmy pracę ze strukturami na przykładzie modelowania bazy danych pracowników danego działu.

Dla uproszczenia, aby uciec od problemów związanych z konwersją informacji przy wejściu, zgodzimy się, że wszystkie pola są symboliczne.

Zdefiniujmy strukturę rekordów tej bazy danych za pomocą następującego szablonu:

Definiowanie danych za pomocą typu struktury

Aby skorzystać ze struktury opisanej za pomocą szablonu w programie, należy zdefiniować zmienną o typie tej struktury. W tym celu używana jest następująca składnia:

[nazwa zmiennej] struct_name

    nazwa zmiennej - identyfikator zmiennej tego typu strukturalnego.

    Nazwa zmiennej jest opcjonalna. Jeśli tego nie określisz, obszar pamięci o rozmiarze równym sumie długości wszystkich elementów konstrukcji zostanie po prostu przydzielony.

    lista wartości - rozdzielona przecinkami lista wartości początkowych elementów konstrukcji ujęta w nawiasy ostre.

    Jego przydział również jest opcjonalny.

    Jeśli lista jest niekompletna, wszystkie pola struktury dla tej zmiennej są inicjalizowane wartościami z szablonu, jeśli takie istnieją.

    Dopuszcza się inicjalizację poszczególnych pól, ale w tym przypadku brakujące pola należy oddzielić przecinkami. Brakujące pola zostaną zainicjalizowane wartościami z szablonu struktury. Jeżeli definiując nową zmienną o typie tej struktury zgadzamy się ze wszystkimi wartościami pól w jej szablonie (czyli ustawionymi domyślnie), to wystarczy wpisać nawiasy ostre.

    Na przykład: zwycięski robotnik.

Na przykład zdefiniujmy kilka zmiennych o typie struktury opisanej powyżej.

Metody pracy ze strukturą

Ideą wprowadzenia typu strukturalnego do dowolnego języka programowania jest połączenie zmiennych różnych typów w jeden obiekt.

Język musi mieć środki dostępu do tych zmiennych w ramach określonej instancji struktury. Aby odnieść się do pola o jakiejś strukturze w poleceniu, używany jest specjalny operator - symbol ". "(punkt)... Jest używany w następującej składni:

    address_expression- identyfikator zmiennej pewnego typu strukturalnego lub wyrażenie w nawiasach zgodnie z przedstawionymi poniżej regułami składniowymi (rys. 1);

    nazwa_pola_struktury - nazwa pola z szablonu konstrukcji.

    W rzeczywistości jest to również adres, a raczej przesunięcie pola od początku struktury.

Zatem operator „ . „(kropka) ocenia wyrażenie

Figa. pięć. Składnia wyrażenia adresowego w operatorze dostępu do pola struktury

Pokażmy na przykładzie struktury, którą zdefiniowaliśmy pracownik niektóre techniki pracy ze strukturami.

Na przykład wypakuj topór wartości pól z wiekiem. Ponieważ mało prawdopodobne jest, aby wiek osoby pełnosprawnej przekroczył 99 lat, to po umieszczeniu w rejestrze treści tego pola znakowego topór wygodnie będzie przekonwertować go na reprezentację binarną za pomocą polecenia aad.

Uważaj, bo ze względu na zasadę przechowywania danych „Najmniej znaczący bajt, co najmniej znaczący adres” najwyższa cyfra wieku zostanie umieszczona w glin, a najmłodszy - w ah.

Aby dostosować, po prostu użyj polecenia xchg al, ah:

mov ax, słowo ptr sotr1.age; w każdym wieku sotr1

lub możesz to zrobić:

Dalsza praca z tablicą struktur odbywa się w taki sam sposób, jak z tablicą jednowymiarową. W tym miejscu pojawia się kilka pytań:

A co z rozmiarem i jak zorganizować indeksowanie elementów tablicy?

Podobnie jak w przypadku innych identyfikatorów zdefiniowanych w programie, translator przypisuje do atrybutu typu nazwę typu konstrukcji oraz nazwę zmiennej o typie struktury. Wartością tego atrybutu jest rozmiar w bajtach zajmowany przez pola tej struktury. Możesz pobrać tę wartość za pomocą operatora rodzaj.

Po poznaniu rozmiaru instancji struktury nie jest trudno zorganizować indeksowanie w tablicy struktur.

Na przykład:

Jak skopiować pole z jednej struktury do odpowiadającego mu pola innej struktury? Albo jak kopiujesz całą strukturę? Skopiujmy to pole nam trzeci pracownik w tej dziedzinie nam piąty pracownik:

mas_sotr pracownik 10 dup ()

mov bx, przesunięcie mas_sotr

mov si, (typ pracownik) * 2; si \u003d 77 * 2

mov di, (typ pracownik) * 4; si \u003d 77 * 4

Wydaje mi się, że zawód programisty prędzej czy później sprawia, że \u200b\u200bczłowiek wygląda na dobrą gospodynię domową. On, podobnie jak ona, nieustannie szuka miejsca, w którym można coś zapisać, ograniczyć i zrobić wspaniały obiad z minimum produktów. A jeśli to się powiedzie, satysfakcja moralna zostanie osiągnięta nie mniej, a może więcej, niż ze wspaniałej kolacji z gospodynią domową. Wydaje mi się, że stopień tej satysfakcji zależy od stopnia miłości do zawodu.

Z drugiej strony sukcesy w rozwoju oprogramowania i sprzętu nieco odprężają programistę i dość często obserwuje się sytuację podobną do znanego przysłowia o muchie i słoniu - do rozwiązania jakiegoś drobnego problemu stosuje się ciężkie środki, których skuteczność w ogólnym przypadku ma znaczenie tylko wtedy, gdy realizacja stosunkowo dużych projektów.

Obecność następujących dwóch typów danych w języku prawdopodobnie tłumaczy się chęcią „hostessy” do możliwie efektywnego wykorzystania obszaru roboczego stołu (RAM) podczas przygotowywania posiłków lub umieszczania produktów (dane programu).

Wprowadzenie.

Nazwany jest język, w którym napisany jest oryginalny program wejściejęzyk, a język, na który jest tłumaczony do wykonania przez procesor-rom to weekendjęzyk. Proces konwersji języka wejściowego na język wyjściowy to tzw nadawanie.Ponieważ procesory mogą wykonywać programy w języku maszynowym kodów binarnych, który nie jest używany do programowania, konieczne jest tłumaczenie wszystkich programów źródłowych. Znany dwie drogitłumaczenia: kompilacja i interpretacja.

Kiedy kompilacjaoryginalny program jest najpierw w całości tłumaczony na równoważny program w języku wyjściowym o nazwie obiektprogram, a następnie wykonany. Ten proces jest realizowany za pomocą specjalnego programy,nazywa kompilator.Wywoływany jest kompilator, dla którego język wejściowy jest symboliczną reprezentacją języka maszynowego (wyjściowego) kodów binarnych monter.

Kiedy interpretacjakażdy wiersz programu źródłowego jest analizowany (interpretowany), a polecenie w nim określone jest natychmiast wykonywane. Wykonanie tej metody jest powierzone program tłumacza.Interpretacja zajmuje dużo czasu. Aby poprawić jego wydajność, zamiast przetwarzać każdą linię, interpreter wstępnie konwertuje wszystkie zespółciągi do znaków (

). Wygenerowana sekwencja symboli służy do wykonywania funkcji przypisanych do oryginalnego programu.

Język asemblera omówiony poniżej jest implementowany przy użyciu kompilacji.

Cechy języka.

Główne cechy asemblera:

● zamiast kodów binarnych język używa nazw symbolicznych - mnemonika.Na przykład dla polecenia dodawania (

) używany jest mnemonik

Odejmowanie (

mnożenie (

Dywizje (

itd. Nazwy symboliczne są również używane do adresowania komórek pamięci. Do programowania w języku asemblera, zamiast kodów binarnych i adresów, wystarczy znać nazwy symboliczne, które asembler tłumaczy na kody binarne;

każde stwierdzenie pasuje jedno polecenie maszyny(kod), to znaczy istnieje zgodność jeden do jednego między instrukcjami maszynowymi a operatorami w programie w języku asemblerowym;

● język zapewnia dostęp do wszystkich obiektówi zespoły. Języki wysokiego poziomu nie mają takiej możliwości. Na przykład język asemblera pozwala sprawdzić rejestr bitów flag i język wysokiego poziomu (na przykład

) nie ma takiej możliwości. Zwróć uwagę, że języki programowania systemu (na przykład C) często zajmują pozycję pośrednią. Jeśli chodzi o dostępność, są bliżej języka asemblera, ale mają składnię wysokiego poziomu;

● język asemblera nie jest językiem uniwersalnym.Dla każdej określonej grupy mikroprocesorów ma swój własny asembler. Języki wysokiego poziomu nie mają tej wady.

W przeciwieństwie do języków wysokiego poziomu, pisanie i debugowanie programu w języku asemblerowym jest czasochłonne. Mimo to język asemblera otrzymał szerokie zastosowaniez powodu następujących okoliczności:

● program napisany w języku asemblera jest znacznie mniejszy i szybszy niż program napisany w języku wysokiego poziomu. W przypadku niektórych aplikacji wskaźniki te odgrywają główną rolę, na przykład wiele programów systemowych (w tym kompilatorów), programy na kartach kredytowych, telefonach komórkowych, sterownikach urządzeń itp.;

● niektóre procedury wymagają pełnego dostępu do sprzętu, co zwykle nie jest możliwe w języku wysokiego poziomu. Ten przypadek obejmuje przerwania i programy obsługi przerwań w systemach operacyjnych, a także kontrolery urządzeń w systemach wbudowanych, które działają w czasie rzeczywistym.

W większości programów tylko niewielki procent całkowitego kodu jest odpowiedzialny za duży procent czasu wykonywania programu. Zazwyczaj 1% programu odpowiada za 50% czasu wykonania, a 10% programu odpowiada za 90% czasu wykonania. Dlatego do napisania konkretnego programu w rzeczywistych warunkach używa się zarówno asemblera, jak i jednego z języków wysokiego poziomu.

Format operatora w języku asemblera.

Program w języku asemblerowym to lista poleceń (instrukcji, zdań), z których każde zajmuje oddzielną linię i zawiera cztery pola: pole etykiety, pole operacji, pole operandu i pole komentarza. Każde pole ma osobną kolumnę.

Pole etykiety.

Kolumna 1 jest przypisana do pola etykiety. Etykieta jest nazwą symboliczną lub identyfikatorem, adresypamięć. Jest to konieczne, aby móc:

● wykonać warunkowy lub bezwarunkowy skok do polecenia;

● uzyskać dostęp do miejsca, w którym przechowywane są dane.

Takie stwierdzenia są oznaczone. Do oznaczenia nazwy używa się (wielkich) liter alfabetu angielskiego i cyfr. Nazwa musi być poprzedzona literą, a na końcu należy umieścić separator dwukropka. Etykietę z dwukropkiem można zapisać w osobnym wierszu, a kod operacji w następnym wierszu w kolumnie 2, co upraszcza pracę kompilatora. Brak dwukropka nie pozwala na odróżnienie etykiety od kodu operacyjnego, jeśli znajdują się one w oddzielnych wierszach.

W niektórych wersjach języka asemblera dwukropki są umieszczane tylko po etykietach poleceń, ale nie po etykietach danych, a długość etykiety może być ograniczona do 6 lub 8 znaków.

W polu etykiety nie powinno być identycznych nazw, ponieważ etykieta jest powiązana z adresami poleceń. Jeżeli podczas wykonywania programu nie ma potrzeby wywoływania polecenia lub danych z pamięci, to pole etykiety pozostaje puste.

Pole kodu operacji.

To pole zawiera mnemoniczny kod polecenia lub pseudo rozkazu (patrz poniżej). Kod mnemoniczny poleceń jest wybierany przez projektantów języka. W języku asemblera

wybrany mnemonik do załadowania rejestru z pamięci

), a zapisanie zawartości rejestru w pamięci - mnemonik

). W językach asemblera

dla obu operacji można użyć odpowiednio jednej nazwy

Jeśli wybór nazw mnemonicznych może być dowolny, to potrzeba użycia dwóch instrukcji maszynowych wynika z architektury procesorów

Mnemonik rejestru zależy również od wersji asemblera (tabela 5.2.1).

Pole operandowe.

Dodatkowe informacje wymagane do ukończenia operacji znajdują się tutaj. W polu operandów instrukcji skoku wskazywany jest adres, na który chcesz wykonać skok, a także adresy i rejestry, które są argumentami instrukcji maszynowej. Jako przykład podamy operandy, które mogą być używane dla procesorów 8-bitowych

● dane liczbowe,

prezentowane w różnych systemach liczbowych. Aby określić używany system liczbowy, po stałej następuje jedna z liter łacińskich: B,

W związku z tym systemy liczb dwójkowych, ósemkowych, szesnastkowych i dziesiętnych (

nie musisz tego zapisywać). Jeśli pierwszą cyfrą liczby szesnastkowej jest A, B, C,

Następnie na początku dodaje się nieznaczne 0 (zero);

● kody rejestrów wewnętrznych mikroprocesora i komórek pamięci

M (źródła lub odbiorcy informacji) w postaci liter A, B, C,

M lub ich adresy w dowolnym systemie liczbowym (na przykład 10B - adres rejestru

w systemie binarnym);

● identyfikatory,

dla par rejestrowych statków powietrznych,

Pierwsze litery B,

H; za parę akumulatorów i rejestr znaków -

; dla licznika poleceń -

; dla wskaźnika stosu -

● etykiety wskazujące adresy argumentów lub następne instrukcje warunku

(jeśli warunek jest spełniony) i bezwarunkowe skoki.Na przykład operand M1 w poleceniu

oznacza konieczność bezwarunkowego skoku do polecenia, którego adres w polu etykiety oznaczony jest identyfikatorem M1;

● wyrażenia,

które są budowane poprzez łączenie danych omówionych powyżej za pomocą operatorów arytmetycznych i logicznych. Należy pamiętać, że sposób, w jaki miejsce na dane jest rezerwowane, zależy od wersji językowej. Programiści asemblera dla

Zdefiniuj słowo), a później wprowadzono alternatywę.

który od początku był w języku procesorów

W wersji językowej

używany przez

Zdefiniuj stałą).

Procesory przetwarzają operandy o różnych długościach. Aby to zdefiniować, programiści asemblera podjęli różne decyzje, na przykład:

Rejestry II o różnej długości mają różne nazwy: ЕАХ - do umieszczania 32-bitowych operandów (typ

); АХ - dla 16-bitów (typ

i AH - dla 8-bitów (typ

● dla przetwórców

przyrostki są dodawane do każdego kodu operacji: sufiks

Do typu

; przyrostek „.B” dla typu

dla operandów o różnych długościach używane są różne rozkazy, na przykład do załadowania bajtu, pół słowa (

) i słowa w rejestrze 64-bitowym, używane są kody rozkazów

odpowiednio.

Pole komentarzy.

To pole zawiera wyjaśnienia dotyczące działań programu. Komentarze nie mają wpływu na działanie programu i są przeznaczone dla ludzi. Mogą być potrzebne do modyfikacji programu, co bez takich komentarzy może być zupełnie niezrozumiałe nawet dla doświadczonych programistów. Komentarz zaczyna się od symbolu i służy do wyjaśniania i dokumentowania programów. Początkowym znakiem komentarza może być:

● średnik (;) w językach dla firm procesorów

● wykrzyknik (!) W językach dla

Każda oddzielna linia komentarza jest poprzedzona znakiem początkowym.

Pseudo rozkazy (dyrektywy).

W języku asemblera istnieją dwa główne typy poleceń:

podstawowyinstrukcje, które są równoważne z kodem maszynowym procesora. Te polecenia wykonują całe przetwarzanie zapewniane przez program;

pseudo rozkazy,lub dyrektywy,przeznaczony do obsługi procesu tłumaczenia programu na język kombinacji kodów. Jako przykład w tabeli. 5.2.2. Pokazane są niektóre pseudo rozkazy z próbnika AC

dla rodziny

.

Podczas programowania zdarzają się sytuacje, kiedy zgodnie z algorytmem ten sam ciąg poleceń trzeba powtarzać wielokrotnie. Aby wyjść z tej sytuacji, możesz:

● napisz żądaną sekwencję poleceń, gdy zostanie napotkana. Takie podejście zwiększa rozmiar programu;

● uformuj tę sekwencję w procedurę (podprogram) i wywołaj ją w razie potrzeby. To wyjście ma swoje wady: za każdym razem, gdy trzeba wykonać specjalne polecenie wywołania procedury i polecenie powrotu, co w przypadku krótkiej i często używanej sekwencji może znacznie zmniejszyć szybkość programu.

Najprostszym i najskuteczniejszym sposobem wielokrotnego powtarzania łańcucha poleceń jest użycie makro,które można traktować jako pseudo rozkaz przeznaczony do ponownego rozgłaszania grupy poleceń często napotykanych w programie.

Makro, czyli makro, charakteryzuje się trzema aspektami: makrodefinicja, makrorewers i makrozszerzenie.

Definicja makra

Jest to oznaczenie powtarzającej się sekwencji poleceń programu używanych do odsyłaczy w tekście programu.

Definicja makra ma następującą strukturę:

Lista wyrażeń; Definicja makra

Powyższa struktura definicji makra składa się z trzech części:

● tytuł

makro zawierające nazwę

Pseudo rozkaz

i zestaw parametrów;

● oznaczone kropkami ciałomakro;

● zespół

zakończenia

makra.

Zestaw parametrów definicji makra zawiera listę wszystkich parametrów wymienionych w polu operandu dla wybranej grupy poleceń. Jeżeli te parametry zostały podane w programie wcześniej, to można je pominąć w nagłówku definicji makra.

Aby ponownie złożyć wybraną grupę poleceń, użyj adresu składającego się z nazwy

makra i lista parametrów z innymi wartościami.

Kiedy asembler napotka definicję makra podczas kompilacji, zapisuje ją w tabeli definicji makr. Przy kolejnych występach w programie imię (

) makra asembler zastępuje je treścią makra.

Nazywa się użycie nazwy makra jako kodu operacji cyrkulacja makro(przez wywołanie makra), a jego zastąpienie przez treść makra to ekspansja makr.

Jeśli program jest przedstawiony jako ciąg znaków (litery, cyfry, spacje, znaki interpunkcyjne i powrót karetki do nowego wiersza), to rozwinięcie makra polega na zamianie niektórych ciągów z tego ciągu na inne.

Rozszerzanie makr następuje podczas procesu asemblacji, a nie podczas wykonywania programu. Za sposób manipulowania ciągami znaków odpowiada fundusze makro.

Trwa proces montażu w dwóch przejściach:

● w pierwszym przebiegu wszystkie definicje makr są zapisywane, a wywołania makr są rozszerzane. W tym przypadku oryginalny program jest odczytywany i konwertowany na program, w którym wszystkie definicje makr są usuwane, a każde wywołanie makra jest zastępowane treścią makra;

● w drugim przebiegu wynikowy program jest przetwarzany bez makr.

Sparametryzowane makra.

Aby pracować z powtarzającymi się sekwencjami poleceń, których parametry mogą przyjmować różne wartości, dostępne są następujące definicje makr:

● z rzeczywistyparametry, które są umieszczane w polu operandów wywołania makra;

● z formalnyparametry. W procesie rozwijania makra każdy parametr formalny, który pojawia się w treści makra, jest zastępowany przez odpowiadający mu faktyczny parametr.

za pomocą makr z parametrami.

Program 1 pokazuje dwie podobne sekwencje poleceń, różniące się tym, że pierwsza z nich zamienia P i

I drugi

Program 2 zawiera makro z dwoma parametrami formalnymi P1 i P2. Podczas rozwijania makra każdy znak P1 wewnątrz ciała makra jest zastępowany pierwszym rzeczywistym parametrem (P,

), a P2 jest zastępowane drugim rzeczywistym parametrem (

) z programu nr 1. W makrozonie

program 2 jest oznaczony: P,

Pierwszy rzeczywisty parametr,

Drugi rzeczywisty parametr.

Program 1

Program 2

MOV EBX, Q MOV EAX, Pl

MOV Q, EAX MOV EBX, P2

MOV P, EBX MOV P2, EAX

Rozszerzone możliwości.

Rozważmy kilka zaawansowanych funkcji języka

Jeśli makro zawierające polecenie rozgałęzienia warunkowego i etykietę, do której tworzona jest gałąź, zostanie wywołane dwa lub więcej razy, etykieta zostanie zduplikowana (problem zduplikowanych etykiet), co spowoduje błąd. Dlatego przy każdym wywołaniu jako parametr przypisywana jest osobna etykieta (przez programistę). W języku

etykieta jest zadeklarowana jako lokalna (

), a dzięki zaawansowanym funkcjom asembler automatycznie generuje inną etykietę za każdym razem, gdy makro jest rozwijane.

umożliwia definiowanie makr w ramach innych makr. Ta zaawansowana funkcja jest bardzo przydatna w połączeniu z łączeniem warunkowym. Rozważać

JEŚLI WERSJA ROZMIAR GT 16 M2 MACRO

Makro M2 można zdefiniować w obu częściach instrukcji

Jednak definicja zależy od procesora, na którym jest montowany program: 16-bitowy czy 32-bitowy. Jeśli M1 nie zostanie wywołane, makro M2 nie zostanie w ogóle zdefiniowane.

Inną zaawansowaną funkcją jest to, że makra mogą wywoływać inne makra, w tym siebie - rekurencyjnypołączenie. W tym drugim przypadku, aby nie uzyskać nieskończonej pętli, makro musi przekazać do siebie parametr, który zmienia się z każdym rozwinięciem, i czekten parametr i zakończ rekurencję, gdy parametr osiągnie określoną wartość.

O używaniu makr w asemblerze.

Podczas korzystania z makr asembler musi mieć możliwość wykonywania dwóch funkcji: zachować definicje makri rozszerzanie wywołań makr.

Zachowanie makr.

Wszystkie nazwy makr są przechowywane w tabeli. Po każdej nazwie znajduje się wskaźnik do odpowiedniego makra, aby w razie potrzeby można było je wywołać. Niektóre asemblery mają oddzielną tabelę nazw makr, inne mają tabelę ogólną, w której wraz z nazwami makr znajdują się wszystkie instrukcje maszynowe i dyrektywy.

Podczas napotkania makra podczas montażu utworzony:

nowy element tabeliz nazwą makra, liczbą parametrów i wskaźnikiem do innej tabeli definicji makr, w której będzie przechowywana treść makra;

● lista formalnyparametry.

Następnie treść makra jest odczytywana i zapisywana w tabeli definicji makr, która jest po prostu ciągiem symboli. Parametry formalne znajdujące się w treści pętli są oznaczone specjalnym symbolem.

Wewnętrzna reprezentacja makra

z powyższego przykładu dla programu 2 (str. 244) jest:

MOV EAX, MOV EBX, MOV MOV i

gdzie średnik jest używany jako znak powrotu karetki, a znak ampersand & jako formalny znak parametru.

Rozszerzenie wywołań makr.

Za każdym razem, gdy podczas składania zostanie napotkane makro, jest ono przechowywane w tabeli makr. Kiedy makro jest wywoływane, asembler tymczasowo wstrzymuje odczytywanie danych wejściowych z urządzenia wejściowego i rozpoczyna odczytywanie zapisanej treści makra. Parametry formalne wyodrębnione z treści makra są zastępowane rzeczywistymi parametrami i dostarczane przez wywołanie. Znak & znajdujący się przed parametrami pozwala asemblerowi je rozpoznać.

Pomimo faktu, że istnieje wiele wersji asemblera, procesy montażu mają wspólne cechy i są bardzo podobne. Praca dwuprzebiegowego asemblera została omówiona poniżej.

Asembler dwuprzebiegowy.

Program składa się z wielu operatorów. Dlatego wydaje się, że podczas montażu można użyć następującej sekwencji działań:

● przetłumaczyć to na język maszynowy;

● przenieść odebrany kod maszynowy do pliku, a odpowiednią część zestawienia - do innego pliku;

● powtarzaj powyższe procedury aż do przetłumaczenia całego programu.

Jednak takie podejście nie jest skuteczne. Przykładem jest tak zwany problem linki lookahead.Jeśli pierwsza instrukcja jest skokiem do instrukcji P znajdującej się na samym końcu programu, asembler nie może jej przetłumaczyć. Najpierw musi określić adres operatora P, a do tego konieczne jest przeczytanie całego programu. Nazywa się każde pełne czytanie oryginalnego programu przejście.Pokażmy, jak rozwiązać problem z łączem do przodu za pomocą dwóch przebiegów:

następuje pierwszy przebieg zbieraći zapisz w tabeli wszystkie definicje symboli (w tym etykiety), a przy drugim przebiegu - przeczytaj i złóż każdego operatora. Ta metoda jest stosunkowo prosta, ale drugie przejście przez oryginalny program wymaga dodatkowego czasu spędzonego na operacjach we / wy;

● za pierwszym przejazdem, przekształcaćprogram do postaci pośredniej i zapisz go w tabeli, a drugi przebieg wykonaj nie według programu oryginalnego, ale zgodnie z tabelą. Ta metoda montażu oszczędza czas, ponieważ w drugim przebiegu nie są wykonywane żadne operacje wejścia / wyjścia.

Pierwsze przejście.

Cel pierwszego przejścia- zbuduj tablicę symboli. Jak wspomniano powyżej, kolejnym celem pierwszego przebiegu jest zachowanie wszystkich makr i rozwinięcie wywołań w miarę ich pojawiania się. W konsekwencji zarówno definicja symbolu, jak i rozwinięcie makra odbywają się w jednym przebiegu. Symbolem może być etykieta,lub wartość,któremu przypisano określoną nazwę za pomocą dyrektywy:

; Wartość - rozmiar bufora

Przypisując wartości do nazw symbolicznych w polu etykiety instrukcji, asembler zasadniczo ustawia adresy, które każda instrukcja będzie miała podczas wykonywania programu. Aby to zrobić, asembler podczas procesu montażu zapisuje licznik adresów poleceń(

) jako zmienna specjalna. Na początku pierwszego przebiegu wartość zmiennej specjalnej jest ustawiana na 0 i zwiększa się po każdym przetworzonym poleceniu o długość tego polecenia. Jako przykład w tabeli. 5.2.3 pokazuje fragment programu wskazujący długość poleceń i wartości licznika. W pierwszym przejściu tworzone są tabele nazwy symboliczne, dyrektywyi kody operacyjne,i jeśli to konieczne dosłownystół. Literał to stała, dla której asembler automatycznie rezerwuje pamięć. Od razu zauważamy, że nowoczesne procesory zawierają instrukcje z bezpośrednimi adresami, więc ich samplery ac nie obsługują literałów.

Symboliczna tabela nazw

zawiera jeden element dla każdej nazwy (tabela 5.2.4). Każdy element tabeli nazw symbolicznych zawiera samą nazwę (lub wskaźnik do niej), jej wartość liczbową, a czasem dodatkowe informacje, które mogą obejmować:

● długość pola danych skojarzonego z symbolem;

● bity realokacji pamięci (które pokazują, czy wartość symbolu zmienia się, jeśli program jest ładowany pod innym adresem niż zamierzał asembler);

● informacja o tym, czy do symbolu można dostać się spoza procedury.

Nazwy symboliczne to etykiety. Można je określić za pomocą operatorów (na przykład

Tabela dyrektyw.

Ta tabela zawiera listę wszystkich dyrektyw lub pseudo rozkazów, które można napotkać podczas asemblacji programu.

Tabela kodów operacji.

Dla każdego kodu operacji tabela zawiera oddzielne kolumny: oznaczenie kodu operacji, argument 1, argument 2, wartość szesnastkowa kodu operacji, długość polecenia i typ polecenia (Tabela 5.2.5). Kody operacji są podzielone na grupy w zależności od liczby i typu argumentów. Typ polecenia określa numer grupy i określa procedurę, która jest wywoływana w celu przetwarzania wszystkich poleceń w tej grupie.

Drugie przejście.

Cel drugiego przejścia- utworzenie programu obiektowego i wydruk w razie potrzeby protokołu montażu; wyprowadzanie informacji potrzebnych konsolidatorowi do łączenia procedur składanych w różnym czasie w jeden plik wykonywalny.

W drugim przebiegu (podobnie jak w pierwszym) wiersze zawierające instrukcje są odczytywane i przetwarzane jedna po drugiej. Oryginalny operator i wynikowy wynik w systemie szesnastkowym obiektkod można wydrukować lub buforować do późniejszego wydrukowania. Po wyzerowaniu licznika adresu polecenia wywoływana jest następna instrukcja.

Oryginalny program może zawierać błędy, na przykład:

dany symbol jest niezdefiniowany lub zdefiniowany więcej niż raz;

● kod operacji jest reprezentowany przez nieprawidłową nazwę (z powodu literówki), nie zawiera wystarczającej liczby operandów lub ma zbyt wiele operandów;

● nie ma operatora

Niektórzy asemblerzy mogą pobrać niezdefiniowany znak i zastąpić go. Jednak w większości przypadków, gdy zostanie wykryta instrukcja z błędem, asembler wyświetla komunikat o błędzie na ekranie i próbuje kontynuować proces asemblacji.

Artykuły poświęcone językowi asemblerowemu.

Aby maszyna mogła wykonywać ludzkie polecenia na poziomie sprzętowym, konieczne jest ustawienie określonej sekwencji działań w języku „zer i jedynek”. Asembler zostanie w tej sprawie pomocnikiem. Jest to narzędzie, które obsługuje tłumaczenie poleceń na język maszynowy. Jednak pisanie programu to bardzo pracochłonny i skomplikowany proces. Ten język nie jest przeznaczony do tworzenia łatwych i prostych działań. W tej chwili dowolny używany język programowania (asembler działa świetnie) pozwala na pisanie specjalnych wydajnych zadań, które znacząco wpływają na działanie sprzętu. Głównym celem jest tworzenie mikroinstrukcji i małych kodów. Ten język daje więcej możliwości niż np. Pascal czy C.

Krótki opis języków asemblera

Wszystkie języki programowania są podzielone na poziomy: niski i wysoki. Każdy z systemów syntaktycznych „rodziny” asemblerów różni się tym, że łączy w sobie od razu niektóre zalety najbardziej rozpowszechnionych i współczesnych języków. Łączy je z innymi to, że system komputerowy może być w pełni wykorzystany.

Charakterystyczną cechą kompilatora jest łatwość obsługi. Tym różni się od tych, które działają tylko z wysokimi poziomami. Jeśli weźmiesz pod uwagę dowolny taki język programowania, Assembler jest dwa razy szybszy i lepszy. Napisanie w nim lekkiego programu nie zajmuje zbyt dużo czasu.

Krótko o strukturze języka

Jeśli mówimy ogólnie o pracy i strukturze funkcjonowania języka, możemy z całą pewnością powiedzieć, że jego polecenia w pełni odpowiadają poleceniom procesora. Oznacza to, że asembler używa kodów mnemonicznych, które są najwygodniejsze do pisania dla ludzi.

W przeciwieństwie do innych języków programowania, Assembler używa określonych etykiet zamiast adresów do zapisywania lokalizacji pamięci. Są one tłumaczone na tzw. Dyrektywy wraz z procesem wykonywania kodu. Są to adresy względne, które nie wpływają na procesor (nie są tłumaczone na język maszynowy), ale są niezbędne do rozpoznania przez samo środowisko programistyczne.

Każda linia procesora ma swoją własną, w takiej sytuacji każdy proces, w tym przetłumaczony, będzie poprawny

Asembler ma kilka składni, które zostaną omówione w artykule.

Plusy języka

Najważniejszą i wygodną cechą asemblera będzie to, że możesz napisać w nim dowolny program dla procesora, który będzie bardzo kompaktowy. Jeśli kod okaże się ogromny, to niektóre procesy są przekierowywane do pamięci RAM. Jednocześnie wszystko robią dość szybko i bezawaryjnie, o ile oczywiście steruje nimi wykwalifikowany programista.

Sterowniki, systemy operacyjne, BIOS, kompilatory, interpretery itp. To programy w języku asemblerowym.

Korzystając z dezasemblera, który tłumaczy z maszyny na maszynę, możesz łatwo zrozumieć, jak działa określone zadanie systemowe, nawet jeśli nie ma na to wyjaśnienia. Jest to jednak możliwe tylko wtedy, gdy programy są lekkie. Niestety, zrozumienie nietrywialnych kodów jest dość trudne.

Wady języka

Niestety początkującym programistom (i często profesjonalistom) trudno jest przeanalizować język. Asembler wymaga szczegółowego opisu wymaganego polecenia. Ze względu na konieczność korzystania z instrukcji maszynowych wzrasta prawdopodobieństwo błędnych działań oraz złożoność wykonania.

Aby napisać nawet najprostszy program, programista musi być wykwalifikowany, a jego poziom wiedzy jest wystarczająco wysoki. Przeciętny specjalista niestety często pisze złe kody.

Jeśli platforma, dla której tworzony jest program, jest aktualizowana, wszystkie polecenia muszą zostać przepisane ręcznie - wymaga tego sam język. Asembler nie wspiera funkcji automatycznej regulacji kondycji procesów i wymiany jakichkolwiek elementów.

Polecenia językowe

Jak wspomniano powyżej, każdy procesor ma swój własny zestaw instrukcji. Najprostszymi elementami, które są rozpoznawane przez dowolny typ, są następujące kody:


Korzystanie z dyrektyw

Programowanie mikrokontrolerów w języku (Assembler na to pozwala i doskonale radzi sobie z funkcjonowaniem) najniższego poziomu w większości przypadków kończy się pomyślnie. Najlepiej jest używać procesorów o ograniczonych zasobach. W przypadku technologii 32-bitowej ten język jest doskonały. Często można zobaczyć dyrektywy w kodach. Co to jest? A do czego to służy?

Po pierwsze, należy podkreślić, że dyrektywy nie są tłumaczone na język maszynowy. Decydują o tym, jak działa kompilator. W przeciwieństwie do poleceń te parametry, mające różne funkcje, różnią się nie z powodu różnych procesorów, ale z powodu innego tłumacza. Wśród głównych dyrektyw są następujące:


pochodzenie nazwy

Dlaczego język otrzymał swoją nazwę - „asembler”? Mowa o tłumaczu i kompilatorze, który szyfruje dane. W języku angielskim asembler to nic innego jak asembler. Program nie był montowany ręcznie, zastosowano konstrukcję automatyczną. Co więcej, w tej chwili różnica między terminami już zniknęła z użytkowników i specjalistów. Język asemblera jest często nazywany językami programowania, chociaż jest to tylko narzędzie.

Ze względu na ogólnie przyjętą nazwę zbiorową niektórzy ludzie podejmują błędną decyzję, że istnieje jeden język niskiego poziomu (lub jego standardowe normy). Aby programista mógł zrozumieć, o jakiej strukturze mówimy, konieczne jest wyjaśnienie, dla której platformy używany jest ten lub inny język asemblera.

Narzędzia makr

Języki asemblera, które są stosunkowo nowe, mają funkcje makr. Ułatwiają pisanie i uruchamianie programu. Dzięki ich obecności tłumacz wielokrotnie wykonuje napisany kod. Podczas tworzenia warunkowego wyboru można napisać ogromny blok poleceń, ale łatwiej jest używać narzędzi makr. Pozwolą ci szybko przełączać się między działaniami w przypadku spełnienia lub nie spełnienia warunku.

Korzystając z dyrektyw języka makr, programista otrzymuje makra asemblera. Czasami ma szerokie zastosowanie, a czasami jego funkcjonalność sprowadza się do jednego polecenia. Ich obecność w kodzie ułatwia pracę z nim, czyni go bardziej przejrzystym i intuicyjnym. Należy jednak zachować ostrożność - w niektórych przypadkach makra wręcz przeciwnie, pogarszają sytuację.

DZWON

Są tacy, którzy czytają tę wiadomość przed wami.
Zapisz się, aby otrzymywać najnowsze artykuły.
E-mail
Imię
Nazwisko
Jak chcesz przeczytać The Bell
Bez spamu