IT rekvalifikácia. Seniorní programátori zarábajú až 6 000 €/mesiac a rekvalifikácia je prvým krokom. Zisti, ako na to!

10. diel - Assembler - Kombinácia skokov a príznaky

V minulej lekcii, Assembler - Podmienené a nepodmienené skoky , sme si povedali niečo o nepodmienených a podmienených skokoch, pomocou ktorých môžeme vytvoriť podmienky a cykly známe z vyšších jazykov.

V dnešnom ASM tutoriálu sa naučíme kombinovať podmienené a nepodmienené skoky, zistíme, ako skokové inštrukcie získajú výsledok z CMP a ako porovnávať signed čísla.

Príklad - Podmienené a nepodmienené skoky dohromady

Hovorili sme si, že môžeme podmienené a nepodmienené skoky ľahko kombinovať. Ukážme si teda na príklade, ako sa používajú dohromady:

zacatek:
mov cx, 5

.znovu:
mov si, message
call print_string

dec cx

cmp cx, 0
jz .return
jmp .znovu

.return:
mov si, konec
call print_string
ret

print_string:
lodsb
cmp al, 0
jz .return
mov ah, 0eh
mov bx, 7h
int 10h
jmp print_string

.return:
ret

message db 'CX != 0', 13, 10, 0
konec db 'CX == 0', 0

Z kódy by ste už mali vyčítať, že vypisuje text 5x, teda dokiaľ nie je CX rovné 0. Vyskúšali sme si tak aj inštrukciu DEC k zníženiu hodnoty a vlastne sme si napísali inštrukciu loop.

Všimnite si použitie funkcie print_string, ktorú som už používali, ako príkladu. A tiež. že ak dáme pred návesťou ., Stane sa z neho "pod-návesťou" a nemusíme tak používať očíslovanie pod. (Platí pre NASM).

Príznaky

Už vieme, že CMP vykoná operáciu A - B a na jej výsledok potom pomocou ďalších inštrukcií reagujeme. Ako ale tieto inštrukcie vedia, aký výsledok bol? CMP totiž podľa výsledku porovnania nastaví tzv. Flagy (príznakmi) a nasledujúce skákacie inštrukcie reagujú na hodnoty uložené v týchto príznakoch.

Ak poznáte princípy počítačov, viete, že odčítanie sa vnútorne vykonáva ako pripočítanie dvojkového doplnku druhého čísla.

Flagy nastavuje okrem CMP aj niekoľko ďalších inštrukcií a nemusí nastaviť všetky, ale len niektoré z nich. Nie sú teda len záležitosť porovnávanie, ale aj niekoľkých ďalších inštrukcií, napr. I tých aritmetických.

Flagy môžu byť vždy buď 1 alebo 0. V registri EFLAGS je veľké množstvo flagov, ale v podmienených skokoch sa používajú len tieto flagy:

  • ZF - Zero flag - Nastaví sa, ak je výsledok 0.
  • SF - Sign flag - Nastaví sa, ak je najvyšší bit výsledku operácie 1 (MSB ako Most Significant Bit, obvykle ten najviac vľavo). Názov pochádza od toho, že ak je číslo uložené ako signed, tak tento bit v čísle označuje, či je číslo záporné alebo nie.
  • CF - Carry flag - Nastaví sa, ak pri operácii došlo k pretečeniu (napr. Pripočítame 1 k 255 v premennej s veľkosťou 1 bajt). Výsledok bude teda 0, ale zapne sa flag Carry. Ak máme signed číslo, tak tam sa o pretečeniu dozvieme z Flag overflow nižšie.
  • OF - Overflow flag - Nastaví sa, ak dôjde k pretečeniu hodnoty signed čísla (pre tento typ čísel nemožno na overenie pretečeniu použiť Carry flag).
  • PF - Parity flag - Flag parity sa nastaví, pokiaľ je v najnižšom bajtu výsledku párny počet jednotkových bitov.

Tabuľka skokov vrátane príznakov a porovnávanie signed čísel

Keďže už poznáme flagy, môžeme si uviesť ďalšie, kompletnejšie tabuľku skokov a uviesť do nej na aký flag nastavený pomocou CMP daná skoková inštrukcia reaguje. Tiež si pridáme inštrukcie pre prácu so signed číslami. Takých tabuliek nás čaká ešte veľa, ASM je veľa o tabuľkách inštrukcií:)

inštrukcie Porovnanie popis typ čísel flagy
JO (Jump if Overflow) Skočí, ak došlo k pretečeniu OF == 1
JNO (Jump if Not Overflow) Skočí, ak nedošlo k pretečeniu OF == 0
JS (Jump if Sign) Skočí, ak bol nastavený sign bit SF == 1
JNS (Jump if Not Sign) Skočí, pokiaľ nebol nastavený sign bit SF == 0
JE (Jump if Equal)
JZ (Jump if Zero)
A == B Skočí, ak hodnoty rovné
Skočí, ak bol rozdiel hodnôt 0
ZF == 1
JNE (Jump if Not Equal)
JNZ (Jump if Not Zero)
A! = B Skočí, ak hodnoty rovné
Skočí, pokiaľ nebol rozdiel hodnôt 0
ZF == 0
JB (Jump if Below)
JNAE (Jump if Not Above or Equal)
JC (Jump if Carry)
A <B Skočí, ak bol rozdiel hodnôt záporný
Skočí, ak bola hodnota menšia
Skočí, ak bol nastavený flag carry
unsigned CF == 1
JNB (Jump if Not Below)
JAE (Jump if Above or Equal)
JNC (Jump if Not Carry)
A> = B Skočí, pokiaľ nebola hodnota menšia
Skočí, pokiaľ nebol rozdiel hodnôt väčší alebo rovný 0
Skočí, pokiaľ nebol nastavený flag carry
unsigned CF == 0
JBE (Jump if Below or Equal)
JNA (Jump if Not Above)
A <= B Skočí, ak bola hodnota menšia alebo rovná
Skočí, ak bol rozdiel hodnôt menší alebo rovný 0
unsigned CF == 1 alebo ZF == 1
JA (Jump if Above)
JNBE (Jump if Not Below or Equal)
A> B Skočí, ak bola hodnota väčšia
Skočí, ak bol rozdiel hodnôt väčší alebo rovný 0
unsigned CF == 0 a ZF == 0
JL (Jump if Less)
JNGE (Jump if Not Greater or Equal)
A <B Skočí, ak bola hodnota menšia
Skočí, ak hodnota nebola väčšia alebo rovná
signed SF! = OF
JGE (Jump if Greater or Equal)
JNL (Jump if Not Less)
A> = B Skočí, ak bola hodnota väčšia alebo rovná
Skočí, ak hodnota nebola menšia
signed SF == OF
JLE (Jump if Less or Equal)
JNG (Jump if Not Greater)
A <= B Skočí, ak bola hodnota menšia alebo rovná
Skočí, ak hodnota nebola väčšia
signed ZF == 1 alebo SF! = OF
JG (Jump if Greater)
JNLE (Jump if Not Less or Equal)
A> B Skočí, ak bola hodnota väčšia
Skočí, ak hodnota nebola menšia alebo rovná
signed ZF == 0 a SF == OF
JP (Jump if Parity)
JPE (Jump if Parity Even)
Skočí, ak bol nastavený parity bit
Skočí, ak bola párna parita
PF == 1
JNP (Jump if Not Parity)
JPO (Jump if Parity Odd)
Skočí, pokiaľ nebol nastavený parity bit
Skočí, ak bola nepárna parita
PF == 0
Táto tabuľka je stále zjednodušená a neobsahuje inštrukcie pre všetky podmienené skoky, napríklad tie podľa obsahu registrov. Nám však takto bohato stačí:)

Niektoré uvedené skoky podľa príznakov sa nepoužívajú tak často. My ich budeme používať napr. K tomu, aby sme vedeli, či sa nejaká operácia podarila, alebo nie.

V budúcej lekcii, Assembler - Registre procesora , si ukážeme skoro všetky registre procesorov x86 a x64.


 

Predchádzajúci článok
Assembler - Podmienené a nepodmienené skoky
Všetky články v sekcii
Základy assembleri
Preskočiť článok
(neodporúčame)
Assembler - Registre procesora
Článok pre vás napísal Jakub Verner
Avatar
Užívateľské hodnotenie:
Ešte nikto nehodnotil, buď prvý!
Autor se věnuje programování v x86 Assembleru.
Aktivity