Ehtolauseet ja hypyt
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.

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.
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.
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 = 0Vertailu 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ä suuriJGE / JNL: suurempi tai yhtä suuriJB / 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:
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:
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 tapauksessaHuomaa 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:
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, EBXseuraaJG isompimerkitsee "hyppää josEAX>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.
Hakkeroinnin oppiminen alkaa tästä
Sadat interaktiiviset kurssit, virtuaalilabrat ja CTF-haasteet selaimessasi. Aloita ilmainen kokeilu ilman korttitietoja.