Asembler jest językiem programowania niskiego poziomu, co oznacza, że jednej komendzie asemblera odpowiada dokładnie jeden rozkaz procesora. Asembler operuje na rejestrach procesora (między innymi, rzecz jasna). Rejestry procesora to bardzo szybkie elementy elektroniczne, mogące przechowywać informacje (pamięć wewnętrzna procesora).
W programowaniu w asemblerze wykorzystywane będą następujące rejestry:
ogólnego użytku:
;Przykład wykorzystania rejestrów ogólnego użytku do operacji arytmetycznych
MOV AX, 89 ; prześlij do rejestru AX liczbę 89
MOV DX,10 ; prześlij do rejestru DX liczbę 10
ADD AX, DX ; dodaj 89 i 10, a wynik prześlij do AX
akumulator (Rejestr ten najczęściej służy do wykonywania działań matematycznych, ale często w tym rejestrze będziemy umieszczać numery funkcji systemu operacyjnego lub BIOSu, wykonywanych po wykonaniu przerwania):
RAX (64 bity) = EAX (młodsze 32 bity) + starsze 32 bity,
EAX (32 bity) = AX (młodsze 16 bitów) + starsze 16 bitów,
AX = AH (starsze 8 bitów) + AL (młodsze 8 bitów)
;Przykład wykorzystania rejestrów akumulatora do operacji arytmetycznych
MOV AH, 1 ; prześlij do rejestru AH liczbę 1
MOV AL,AH ; kopiuj AH do AL
DEC AL ; odejmij 1 (dekrementacja) od AL - AX ma wartość 1
rejestr bazowy (używany na przykład przy dostępie do tablic):
RBX (64 bity) = EBX (młodsze 32 bity) + starsze 32 bity,
EBX (32 bity) = BX (młodsze 16 bitów) + starsze 16 bitów,
BX = BH (starsze 8 bitów) + BL (młodsze 8 bitów)
;Przykład wykorzystania rejestrów bazowych do operacji na adresach pamięci
MOV AX, 0
MOV DX,AX
MOV BX,6
MOV AL, [BX] ; prześlij do rejestru AL zawartość pamięci spod adresu 6
licznik (używany na przykład do określania ilości powtórzeń pętli):
RCX (64 bity) = ECX (młodsze 32 bity) + starsze 32 bity,
ECX (32 bity) = CX (młodsze 16 bitów) + starsze 16 bitów,
CX = CH (starsze 8 bitów) + CL (młodsze 8 bitów)
;Przykład wykorzystania rejestru licznika w pętli
MOV CX, 5
Zaczynaj_petle: ; etykieta
SUM CX,1 ; dekrementacja
JNZ Zaczynaj_petle ; jeśli CX większe od 0 skok do etykiety
rejestr danych (W tym rejestrze przechowujemy adresy różnych zmiennych):
RDX (64 bity) = EDX (młodsze 32 bity) + starsze 32 bity,
EDX (32 bity) = DX (młodsze 16 bitów) + starsze 16 bitów,
DX = DH (starsze 8 bitów) + DL (młodsze 8 bitów)
rejestry indeksowe (Rejestry indeksowe najczęściej służą do operacji na długich łańcuchach danych, w tym napisach i tablicach):
indeks źródłowy:
RSI (64 bity) = ESI (młodsze 32 bity) + starsze 32 bity,
ESI (32 bity) = SI (młodsze 16 bitów) + starsze 16 bitów,
SI (16 bitów) = SIL (młodsze 8 bitów) + starsze 8 bitów (tylko tryb 64-bit)
indeks docelowy:
RDI (64 bity) = EDI (młodsze 32 bity) + starsze 32 bity,
EDI (32 bity) = DI (młodsze 16 bitów) + starsze 16 bitów,
DI (16 bitów) = DIL (młodsze 8 bitów) + starsze 8 bitów (tylko tryb 64-bit)
rejestry wskaźnikowe:
wskaźnik bazowy (najczęściej służy do dostępu do zmiennych lokalnych):
RBP (64 bity) = EBP (młodsze 32 bity) + starsze 32 bity,
EBP (32 bity) = BP (młodsze 16 bitów) + starsze 16 bitów.
BP (16 bitów) = BPL (młodsze 8 bitów) + starsze 8 bitów (tylko tryb 64-bit)
wskaźnik stosu (Służy do dostępu do stosu):
RSP (64 bity) = ESP (młodsze 32 bity) + starsze 32 bity,
ESP (32 bity) = SP (młodsze 16 bitów) + starsze 16 bitów.
SP (16 bitów) = SPL (młodsze 8 bitów) + starsze 8 bitów (tylko tryb 64-bit)
wskaźnik instrukcji (Mówi procesorowi, skąd ma pobierać instrukcje do wykonywania):
RIP (64 bity) = EIP (młodsze 32 bity) + starsze 32 bity,
EIP (32 bity) = IP (młodsze 16 bitów) + starsze 16 bitów.
rejestry segmentowe (wszystkie 16-bitowe):
segment kodu CS - mówi procesorowi, gdzie znajdują się dla niego instrukcje.
segment danych DS - ten najczęściej pokazuje na miejsce, gdzie trzymamy nasze zmienne.
segment stosu SS - dzięki niemu wiemy, w którym segmencie jest nasz stos. O tym, czym w ogóle jest stos, powiem w następnej części.
segment dodatkowy ES - często używany, gdy chcemy coś napisać lub narysować na ekranie bez pomocy Windows, DOSa czy nawet BIOSu.
FS i GS (dostępne dopiero od 80386) - nie mają specjalnego przeznaczenia. Są tu na wypadek, gdyby zabrakło nam innych rejestrów segmentowych.
rejestr stanu procesora: FLAGI (16-bitowe), E-FLAGI (32-bitowe) lub R-FLAGI (64-bitowe).
Służą one przede wszystkim do badania wyniku ostatniej operacji (na przykład czy nie wystąpiło przepełnienie, czy wynik jest zerem, itp.). Najważniejsze flagi to CF (carry flag - flaga przeniesienia), OF (overflow flag - flaga przepełnienia), SF (sign flag - flaga znaku), ZF (zero flag - flaga zera), IF (interrupt flag - flaga przerwań), PF (parity flag - flaga parzystości), DF (direction flag - flaga kierunku).
Instrukcja MOV nie pozwala na:
kopiowanie komórki pamięci do innej komórki pamięci (MOV [a],[b])
kopiowanie z jednego rejestru segmentowego do drugiego
pisania wartości do rejestru segmentowego