HAKATEMIA
07Hands-on

Ehtolauseet ja hypyt

Keskitaso25MIN

Ehtolauseet ja hypyt

Tähän asti olemme kirjoittaneet ohjelmia, jotka etenevät suoraviivaisesti ylhäältä alas, käsky kerrallaan. Mutta oikeat ohjelmat haarautuvat. Ne tekevät päätöksiä: jos arvo on suurempi kuin nolla, tee jotain, muuten tee jotain muuta. Korkean tason kielten if-else, switch ja silmukat ovat assemblyssä kaikki rakennettu kahdesta peruspalasta: vertailu ja hyppy. EFLAGS-rekisterin bitit ja CMP → liput → Jcc -päätösketju; if-rakenteen käänteinen käännös assemblyyn.

Labelit ja ehdoton hyppy (JMP)

Hypätessämme koodissa tarvitsemme jonkin merkin paikasta, johon hypätään. Tätä kutsutaan labeliksi eli nimiöön. Labelit kirjoitetaan rivin alkuun ja ne päättyvät kaksoispisteeseen.

Koodi
Konsoli
Rekisterit
EAX0
EBX0
ECX0
EDX0
EIP0
ESP256
ESI0
EDI0
EFLAGS
ZF0
SF0
OF0
CF0
DF0
PF0
Muisti
0000
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
0010
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
0020
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
0030
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
0040
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
0050
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
0060
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
0070
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
0080
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
0090
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00a0
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00b0
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00c0
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00d0
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00e0
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00f0
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00

JMP on ehdoton hyppy: suoritus siirtyy aina labelin osoittamaan riviin, ilman ehtoja. Ehdoton hyppy yksin ei vielä tee mitään hyödyllistä; oikeat päätökset tehdään ehdollisilla hypyillä.

Vertailu (CMP) ja EFLAGS-rekisteri

Prosessorissa on erityinen tilarekisteri EFLAGS, jossa on yksittäisiä bittejä, eli lippuja, jotka kertovat edellisen operaation tuloksesta. Tärkeimmät niistä tällä kurssilla:

  • ZF (Zero Flag): 1 jos tulos oli nolla.
  • SF (Sign Flag): 1 jos tulos oli negatiivinen (ylin bitti = 1).
  • CF (Carry Flag): 1 jos operaatiossa tuli ylivuoto etumerkittömässä mielessä.
  • PF (Parity Flag): 1 jos tuloksen alin tavu sisältää parillisen määrän (0, 2, 4, 6 tai 8) ykkösbittejä (harvoin tarpeen).

CMP-käsky on kuin SUB, mutta tulosta ei tallenneta minnekään; se vain päivittää liput laskutoimituksen kohde - lähde perusteella.

X86
1MOV EAX, 7
2CMP EAX, 7    ; 7 - 7 = 0  → ZF = 1
3CMP EAX, 10   ; 7 - 10 = -3 → SF = 1, ZF = 0, CF = 1
4CMP EAX, 3    ; 7 - 3 = 4   → ZF = 0, SF = 0, CF = 0

Vertailu siis kertoo prosessorille, ovatko kaksi arvoa samat tai kumpi on suurempi. Seuraavaksi tehdään päätös lippujen perusteella.

Ehdolliset hypyt

Ehdolliset hypyt katsovat EFLAGS-rekisterin lippuja ja hyppäävät vain, jos ehto täyttyy. Yleisimmät:

  • JE / JZ: hyppää jos yhtä suuri (ZF = 1)
  • JNE / JNZ: hyppää jos eri suuri (ZF = 0)
  • JL / JNGE: hyppää jos pienempi (etumerkillinen vertailu)
  • JG / JNLE: hyppää jos suurempi (etumerkillinen vertailu)
  • JLE / JNG: pienempi tai yhtä suuri
  • JGE / JNL: suurempi tai yhtä suuri
  • JB / JA / JBE / JAE: vastaavat etumerkittömät (below / above).

**Etumerkillinen vs etumerkitön: **Sama bittikuvio voi olla iso positiivinen luku tai pieni negatiivinen, riippuen tulkinnasta. Siksi vertailuhypyille on kaksi versiota. Valitse oikea sen mukaan, miten dataasi pitää tulkita.

if-rakenne assemblyssä

Tarkastellaan pientä esimerkkiä. Korkean tason koodissa kirjoittaisit:

C
1if (eax == 5) {
2    eax = 100;
3}
4// jatkuu...

Assemblyssa sama rakenne käännetään "käänteisesti": vertaillaan ja hypätään yli, jos ehto ei täyty:

X86
1CMP EAX, 5
2JNE jatka       ; jos EAX != 5, hypätään yli
3MOV EAX, 100    ; tämä ajetaan vain jos EAX == 5
4
5jatka:
6; tästä jatkuu suoritus joka tapauksessa

Huomaa kuvio: hyppää yli sen koodin, jonka haluat suoritettavan vain ehdon täyttyessä. Tämä on assemblyn perustyyli.

if-else

Kaksihaaraisessa rakenteessa tarvitaan kaksi labelia ja yksi ehdoton hyppy:

Koodi
Konsoli
Rekisterit
EAX0
EBX0
ECX0
EDX0
EIP0
ESP256
ESI0
EDI0
EFLAGS
ZF0
SF0
OF0
CF0
DF0
PF0
Muisti
0000
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
0010
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
0020
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
0030
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
0040
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
0050
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
0060
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
0070
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
0080
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
0090
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00a0
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00b0
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00c0
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00d0
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00e0
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00f0
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00

Vinkkejä debuggaukseen

  • Kun ohjelma ei käyttäydy odotetusti, aseta breakpoint juuri ennen CMP-riviä ja tutki rekistereiden arvot ennen vertailua.
  • Lue CMP-riviä "ylhäältä alas": CMP EAX, EBX seuraa JG isompi merkitsee "hyppää jos EAX > EBX". Ensimmäinen operandi on aina vertailun "vasen puoli".
  • Jos hyppy ei laukea kuten odotat, tarkista oletko valinnut etumerkillisen (JG/JL) vai etumerkittömän (JA/JB) version.
1 / 3
Hakatemia Pro

Hakkeroinnin oppiminen alkaa tästä

Sadat interaktiiviset kurssit, virtuaalilabrat ja CTF-haasteet selaimessasi. Aloita ilmainen kokeilu ilman korttitietoja.