Struktury kontrolne
- Instrukcja skoku bezwarunkowego
JMP
- Wywołanie podprogramu
CALL
iRET
- Instrukcje warunkowe
CMP
,TEST
,JXX
- Pętle
- Wejście/wyjście z biblioteką asm64_io
- Zadania
- Archiwum
Instrukcja skoku bezwarunkowego JMP
Instrukcja JMP
spowoduje wykonanie skoku bezwarunkowego (goto z języka C) do określonej etykiety
JMP my_label
Wywołanie podprogramu CALL
i RET
Wywołanie podprogramu odbywa się instrukcją CALL
. Dokonuje ona skoku bezwarunkowego pod podany adres (etykietę będącą nazwą podprogramu) jednocześnie odkładając na stos adres powrotu (adres instrukcji występującej bezpośrednio po CALL
). Umożliwia to instrukcji RET
na powrót z podprogramu do miejsca wywołania.
mov eax, 5
call kwadrat ; wywołanie podprogramu kwadrat
...
kwadrat: ; etykieta oznaczająca początek podprogramu
imul eax, eax
ret ; powrót z podprogramu
Instrukcje warunkowe CMP
, TEST
, JXX
Instrukcje warunkowe pozwalają zaimplementować akcję w zależności od wyniku testu czy ostatnich operacji arytmetycznych. Podstawowy test w asemblerze wykonuje się instrukcją CMP, porównującą dwa operandy i ustawiającą odpowiednie flagi rejestru flagowego.
CMP A, B
Działanie instrukcji CMP jest identyczne z SUB A, B z tą różnicą, że wynik nie jest zapamiętywany.
Innym testem jest instrukcja TEST
TEST A, B
Wykonuje on operację bitowego AND A, B ustawiając odpowiednio flagi SF, ZF, PF i zerując OF i CF. Wykorzystuje się ją przede wszystkim by sprawdzić czy dana liczba jest równa 0 np. TEST EAX, EAX lub czy dany bit jest ustawiony np. TEST EAX, maska
Instrukcje skoków warunkowych, przedstawione w Tabeli 1 są wykonywane zazwyczaj bezpośrednio po instrukcji CMP lub TEST (inne instrukcje też mogą ustawiać rejestr flag procesora). Tabela 1 Instrukcje skoków warunkowych
Warunek | Liczby ze znakiem | Liczby bez znaku |
---|---|---|
A == B | JE, JZ | JE, JZ |
A != B | JNE, JNZ | JNE, JNZ |
A < B | JL, JNGE | JB, JNAE |
A <= B | JLE, JNG | JBE, JNA |
A > B | JG, JNLE | JA, JNBE |
A >= B | JGE, JNL | JAE, JNB |
Korzystając z instrukcji przedstawionych powyżej: można w prosty sposób stworzyć bloki kontrolne, odpowiadające konstrukcjom składniowym z języka C, np.:
if ( EAX >= 5 )
EBX = 1;
else
EBX = 2;
można przetłumaczyć na:
cmp eax, 5
jge thenblock
mov ebx, 2
jmp next
thenblock:
mov ebx, 1
next:
Pętle
Instrukcje porównania i skoków można użyć do stworzenia pętli np. pętla for z języka C
for (j=0,i=10; i>0; i--) { j=j+i; }
może być zaimplementowana w sposób następujący:
mov eax, 0
mov ecx, 10 ; ECX to zmienna I. i=10
petla_for:
cmp ecx, 0
jbe koniec_petli ; wychodzimy, gdy i <= 0
add eax, ecx ; EAX to zmienna J. j=j+i
dec ecx ; i=i-1
jmp petla_for koniec_petli:
Inny sposób implementacji pętli for to wykorzystanie instrukcji LOOP
. Powyższy kod może być przepisany do postaci:
mov ecx, 10 ; ECX to zmienna I. i=10
mov eax, 0
petla_for:
add eax, ecx ; EAX to zmienna J. j=j+i
loop petla_for ; zmniejsz ECX o 1 i jeśli różny od
; zera, skocz do: petla_for
Wejście/wyjście z biblioteką asm64_io
Wczytywanie i wypisywanie liczb z assemblera nie jest łatwe. W tym celu można użyć biblioteki asm64_io, która ułatwia wywołanie odpowiednich funkcji języka C z assemblera. Biblioteka ta pozwala też wypisać zawartość rejestrów ułatwiając debugowanie.
Kompilacja własnego pliku w Geany (zakładając, że asm64_io jest skompilowane już w bieżącym katalogu) (nasm “%f” -felf64 -o “%e”.o) && (gcc “%e”.o driver64.o asm64_io.o -o”%e”)
Zadania
Zadanie 1
Napisz program w asemblerze sprawdzający, czy dana liczba jest liczbą pierwszą. Dla liczby n należy sprawdzić czy któraś z liczb naturalnych pomiędzy 2 a pierwiastek z n dzieli n. We wstępnej wersji można sprawdzać do n-1. W wersji podstawowej liczba może być na sztywno wpisana w program. W wersji rozszerzonej wczytujemy liczbę z klawiatury.
Zadanie 2
Napisz funkcję w asemblerze, która wypisze na ekran liczbę całkowitą ze znakiem umieszczona w rejestrze EAX wykorzystując przerwania systemowe. Przed wypisaniem należy zamienić liczbę na łańcuch tekstowy (np. dzielimy w pętli przez 10 z resztą a kolejne cyfry umieszczamy w buforze).
Zadanie 3
Proszę napisać program wypisujący rozkład zadanej liczby na czynniki pierwsze. Można wypisywać posługując się asm_io lub printf. Np. dla liczby 60 wyjście powinno zawierać: 2 2 3 5
Zadanie 4
Napisz program, który dla danej liczby n i przedziału [a, b] wyszuka i wypisze na ekran wszystkie liczby z przedziału [a,b] względnie pierwsze do n. Program może po prostu dla każdej liczby x z przedziału [a,b] obliczać NWD(n,x) i wypisywać liczbę x jeżeli wynik jest równy 1.
Archiwum
Zadanie 5
Napisz program szukający najmniejszej wspólnej wielokrotności dwóch liczb wczytanych z klawiatury.
Zadanie 6
Napisz program szukający liczb pierwszych w zadanym przedziale. Algorytm może po prostu sprawdzać po kolei liczby z zadanego przedziału.