Przedmiot : Programowanie w języku wewnętrznym Ćwiczenie nr 4 str. 1. 1. Użycie Asemblera. Polecenie JMP. Polecenie nakazuje procesorowi wykonywanie kodu programu od nowego innego miejsca. Miejsce to jest identyfikowane poprze etykietę, która na etapie kompilacji jest przekształcane przez asembler na postać adresu. Jeżeli skok jest wykonywany do etykiety w obrębie aktualnego segmentu to przesunięcie etykiety jest ładowane do rejestru IP. Natomiast w przypadku skoku do innego segmentu także adres tego segmentu jest umieszczany w rejestrze CX. Formaty polecenia JMP : JMP SHORT miejsce_docelowe JMP NEAR PTR miejsce_docelowe JMP FAR PTR miejsce_docelowe Polecenie JMP umożliwia skok do etykiety w aktualnej procedurze, skok do innej procedury, do iinego segmentu, do adresu poza aktualnym programem oraz do dowolnego adresu w pamięci RAM i ROM. Przykłady użycia polecenia JMP : jmp K1 : near - miejsce docelowe w aktualnym segmencie jmp near ptr K1 : near - miejsce docelowe w aktualnym segmencie jmp short K2 : short skok do miejsca w zakresie od -128 do 127 bajtów jmp far ptr K3 : far - skok do innego programu Opis operatorów polecenia JMP : short skok do etykiety w zakresie od -128 do 127 bajtów od adresu kolejnego rozkazu. Do rejestru IP jest dodawana 8-bitowa wartość przemieszczenia. near ptr skok do etykiety w dowolnym miejscu aktu1alnego segmentu kodu. W rejestrze IP umieszczana jest 16-bitowa wartość przemieszczenia. far ptr skok do etykiety w inny segmencie. Adres segmentu etykiety umieszczany jest w rejestrze CS, a jej przesunięcie w rejestrze IP. Polecenie LOOP. Polecenie to jest prostym sposobem wykonywania określonego bloku kodu wiele razy. Rejestr CX jest używany jako licznik, który jest zmniejszany przy każdym wykonaniu pętli. Loop odejmuje wartość 1 z rejestru CX, jeżeli CX jest jest większy od zera, to sterowanie jest przekazywane do miejsca docelowego. mov cx, 5 start:... loop start Po osiągnięciu przez licznik wartości 0 skok nie jest wykonywany i wykonywany jest dalszy kod programu. Znacznik Zero nie jest zmieniany pomimo pomimo osiągnięcia przez CX wartości 0. Przykład 1. Program zlicza do 5 inkrementując rejestr AX. mov ax, 0 : ustawienie AX na 0 mov cx, 5 : ustawienie licznika pętli inc ax : inkrementacja rejestru AX 1
loop powtarzanie inkrementacji do momentu osiągnięcia przez CX wartości 0 Przykład 2. Program drukuje na ekranie znak * str. 2. mov cx, 2*10 : ustawienie licznika mov ah, 2 : funkcja Dos wyświetlająca znak mov dl, '*' : wyświetlanie znaku * : wywołanie Dos loop petla Przykład 3. Zmiana licznika pętli. Zmiana licznika pętli w trakcie wykonywania pętli nie jest dobrą techniką programowania. Może to doprowadzić do sytuacji w której licznik nigdy nie osiągnie wartości 0 przez co pętla nigdy się nie skończy. Modyfikacja licznika pętli w językach wysokiego poziomu nie jest możliwa, ponieważ wewnętrzny rejestr nie jest dostępny dla programisty. mov ah, 2 : funkcja Dos wyświetlająca znak mov cx, 2*5 : ustawienie licznika mov dl, '+' : wyświetlanie znaku + : wywołanie Dos inc cx : dodanie 1 do CX!!! loop petla 2. Usuwanie błędów w Asemblerze. Około 20% czasu jest poświęcone na tworzenie kodu, a 80% czasu na usuwanie popełnionych w kodzie błędów. Usuwanie błędów w aplikacjach jest niezwykle cenną umiejętnością. W przypadku wystąpienia błędu asembler wyświetla komunikat zawierający nazwę programu źródłowego, numer wiersza z pliku źródłowego. Błędy w programie Przykład 1. title Przykład błędów end main. Wprowadź powyższy przykład, dokonaj kompilacji i popraw błędy w programie. Jako pomoc użyj analizy programu z pkt. 3. Błędy w programie Przykład 2. title Przykład błędów mov ax, @data 2
mov ds, ax mov ax, value1 mov ah, value2 main endp str. 3. value1 db 0Ah value2 dw 1000h end main Standardowe dyrektywy asemblera : Dyrektywa end endp page proc title.model.stack Opis oznacza koniec asemblowania programu oznacza koniec procedury oznacza ustawienie formatu strony dla pliku wydruku oznacza początek procedury oznacza tytuł pliku wydruku oznacza początek segmentu kodu oznacza początek segmentu danych oznacza ustawienie modelu pamięci oznacza ustawienie wielkości segmentu stosu Dyrektywy alokacji danych - są używane do zarezerwowania miejsca w pamięci na podstawie zdefiniowanych typów danych : Mnemonik Opis Bajty Atrybut DB Definiuje bajt 1 Bajt DW Definiuje słowo 2 Słowo DD Definiuje dwusłowo 4 Dwusłowo DF, DP Definiuje odległy wskaźnik 6 Odległy wskaźnik DQ Definiuje słowo poczwórne 8 Słowo poczwórne DT Definiuje dziesięć bajtów 10 Dziesięć bajtów 3. Przykładowy program w języku Asemblera i jego analiza. Program Hello World : title Program Hello World ( hello.asm ) message db Hello World, 0dh, 0ah, '$' mov ax,@data mov ds, ax mov ah, 9 3
mov dx, offset message main endp end main Powyższy program wyświetla na ekranie napis Hello World. Występują tu najważniejsze składniki programu napisanego w asemblerze. Powyższy kod jest napisany w asemblerze i musi być skompilowany do kodu maszynowego przed uruchomieniem. Program jest zgodny z asemblerami Borlanda i Microsoftu. dyrektywa informuje iż program wykorzystuje strukturę pamięci, w ramach której na dane i kod przeznaczono po 64 kb pamięci..stack - dyrektywa rezerwuje dla programu 100h ( 256 ) bajtów na stosie dyrektywa oznacza początek segmentu danych, w którym przechowywane są zmienne. W ramach deklaracji komunikatu message asembler rezerwuje pamięć dla ciągu Hello World oraz dwa bajty znaków nowego wiersza ( 0dh, 0ah ). Symbol $ jest wymaganym znakiem terminacji ciągu dla określonej podprocedury wyjściowej DOS. dyrektywa oznacza początek segmentu kodu. proc dyrektywa oznacza początek procedury o nazwie main pierwsze dwa polecenia głównej procedury oznaczają, że segment danych (@data) zostanie skopiowany do rejestru DS. kolejna część main jest odpowiedzialna za umieszczenie ciągu znaków na ekranie. Odbywa się to poprzez wywołanie funkcji DOS wyświetlającej ciąg, którego adres jest w rejestrze DX. Numer funkcji jest umieszczany w rejestrze AH. ostatnie dwie instrukcje głównej procedury ( mov ax,4c00h i ) powodują zatrzymanie programu i przekazanie sterowania do systemu operacyjnego. Microsoft Asembler zawiera program ML.EXE. Asembluje on i konsoliduje jeden lub więcej plików źródłowych w języku asembler. Składnia ML.EXE : ML opcje nazwa_pliku.asm Przykłady asemblowania i konsolidowania z różnymi opcjami : ML /Zi hello.asm ; Dołączenie informacji debuggera ML /Fl hello.asm ; Utworzenie pliku wydruku ( hello.lst ) ML /Fm hello.asm ; Utworzenie pliku mapy ( hello.map ) ML /Zm hello.asm ; Tryb zgodności z MASM 5.12 ML /Zi /Zm /Fm /Fl hello.asm ; asemblacja i konsolidacja w jednej linii 4. Zadania do wykonania w ćwiczeniu a).korzystając z opisu przykładu z pkt 3. wykonaj praktycznie przykłady z pkt 1 i 2 kompilując przykłady programem ML z pakietu Masm 6.13. b). Dokonaj analizy poniższego kodu i odpowiedz jaka będzie zawartość rejestru bx po zakończeniu programu. mov cx, 2 cw1: mov bx, 20 loop cw1 4
cw2 : mov bx, 10 c). Wykorzystując program debug napisz program dodający do rejestru BX wartość 5 pięć razy z wykorzystaniem pętli LOOP. Program rozpocznij od polecenia A 100. Następnie wykonaj JMP do adresu 0200, gdzie zapiszesz program odejmujący w pętli LOOP od rejestru BX wartość 5 pięć razy. Jaka będzie końcowa wartość rejestrów BX i CX. Wykorzystując w debugerze śledzenie zademonstruj działanie programu prowadzącemu. d). Program z punktu 4 c). napisz w postaci mnemoniki asemblera, skompiluj z użyciem ML i wykonaj śledzenie skompilowanego programu przy użyciu debugera debug. str. 4. 5