################################ ##### Pinon k„ytt„ytyminen ##### ################################ TKJ 90 Ohjaus 3 teht„v„ 2, kommentteja Seuraavassa ovat suoritetut k„skyt, lyhyt selvitys kunkin k„skyn toiminnasta ja pino KŽSKYN SUORITUKSEN JŽLKEEN! Pino-osoitinta on merkitty SP:ll„ ja kantaosoittimen (Base Pointer) osoittamaa kohtaa pinossa BP:ll„. Numerot kuten 1), 2),... eiv„t liity ohjelmakoodiin vaan ovat selostuksessa tapahtuvia viittauksia varten! Osoite K„sky Pinon rakenne ========================================================================= 1) MOV AX,0003 SP SS:3FFC 0000 Kommentti: Siirret„„n AX-rekisteriin ohjelmassa annettu vakioluku 3 2) PUSH AX SP SS:3FFA 0003 SS:3FFC 0000 V„litet„„n AX aliohjelmalle pinon kautta. AX:n arvo on nyt pinon p„„ll„! 3) CALL PROGRAM.KERTOMA Kutsutaan ohjelman KERTOMA-nimist„ SP SS:3FF8 0039 aliohjelmaa. Pinoon laitetaan paluuosoite, SS:3FFA 0003 eli kutsua seuraavan k„skyn osoite. SS:3FFC 0000 4) 0000 PUSH BP SP SS:3FF6 3FFC SS:3FF8 0039 Tallennetaan Base Pointer pinoon SS:3FFA 0003 aliohjelman suorituksen ajaksi. 5) 0001 MOV BP,SP BP SP SS:3FF6 3FFC Otetaan Base Pointterin uudeksi arvoksi SS:3FF8 0039 Stack Pointterin eli pino-osoittimen arvo. SS:3FFA 0003 Pinossa ei tapahdu muutoksia. SS:3FFC 0000 6) 0003 SUB SP,0002 SP SS:3FF4 ???? Pino-osoitinta v„hennet„„n kahdella, eli BP SS:3FF6 3FFC pinon p„„lle syntyy sanan (=kahden tavun) SS:3FF8 0039 kokoinen "k„ytt„m„t”n" tila. Huomaa: SS:3FFA 0003 pino-osoitin pienenee kun pino kasvaa!! SS:3FFC 0000 ???? tarkoittaa, ett„ arvo voi vaihdella eri suorituskerroilla. 7) 0006 CMP WORD PTR [BP+04],0001 SP SS:3FF4 ???? Verrataan muistipaikassa BP+04 olevaa lukua BP SS:3FF6 3FFC lukuun 1. Nyt BP=3FF6 (kohta 5) eli BP+04=3FFA, SS:3FF8 0039 jossa on luku 0003. BP+04 pit„„ siis sis„ll„„n SS:3FFA 0003 sen arvon, jolla funktiota kutsuttiin. SS:3FFC 0000 8) 000A JG PROGRAM.6 (0013) Edellisen kohdan vertailun perusteella SP SS:3FF4 ???? suoritetaan hyppy (JG=Jump if Greater), BP SS:3FF6 3FFC koska 0003 > 0001. Suoritus jatkuu osoitteesta SS:3FF8 0039 0013 SS:3FFA 0003 SS:3FFC 0000 9) 0013 MOV AX,[BP+04] Valmistaudutaan suorittamaam uusi funktion SP SS:3FF4 ???? KERTOMA kutsu: AX-rekisteriin siirret„„n BP SS:3FF6 3FFC edellisen kutsun yhteydess„ saatu n:n arvo. SS:3FF8 0039 Pino ei muutu. SS:3FFA 0003 SS:3FFC 0000 10) 0016 DEC AX V„hennet„„n AX:„„ yhdell„. Pino ei muutu. SP SS:3FF4 ???? BP SS:3FF6 3FFC SS:3FF8 0039 SS:3FFA 0003 SS:3FFC 0000 11) 0017 PUSH AX Talletetaan AX-rekisteri pinoon jossa SP SS:3FF2 0002 se v„littyy aliohjelmalle kuten kohdassa 2. SS:3FF4 ???? BP SS:3FF6 3FFC SS:3FF8 0039 SS:3FFA 0003 SS:3FFC 0000 12) 0018 CALL PROGRAM.KERTOMA Kutsutaan uudelleen aliohjelmaa KERTOMA, SP SS:3FF0 001B eli t„ss„ tapauksessa se kutsuu itse itse„„n SS:3FF2 0002 mutta v„hennetty„„n parametrista ykk”sen. SS:3FF4 ???? (Pascaliksi: kertoma:=kertoma(n-1); miss„ BP SS:3FF6 3FFC n=AX.) SS:3FF8 0039 SS:3FFA 0003 SS:3FFC 0000 13) 0000 PUSH BP Aliohjelma tallettaa Base Pointerin kuten SP SS:3FEE 3FF6 kohdassa 4. SS:3FF0 001B SS:3FF2 0002 SS:3FF4 ???? BP SS:3FF6 3FFC SS:3FF8 0039 SS:3FFA 0003 SS:3FFC 0000 14) 0001 MOVE BP,SP Kuten kohdassa 5. BP SP SS:3FEE 3FF6 SS:3FF0 001B SS:3FF2 0002 SS:3FF4 ???? SS:3FF6 3FFC SS:3FF8 0039 SS:3FFA 0003 SS:3FFC 0000 15) 0003 SUB SP,0002 Kuten kohdassa 6. Pinon p„„lle "tehd„„n SP SS:3FEC ???? tilaa". BP SS:3FEE 3FF6 SS:3FF0 001B SS:3FF2 0002 SS:3FF4 ???? SS:3FF6 3FFC SS:3FF8 0039 SS:3FFA 0003 SS:3FFC 0000 16) 0006 CMP WORD PTR [BP+04],0001 Kuten kohdassa 7: Verrataan paikassa BP+04 SP SS:3FEC ???? BP SS:3FEE 3FF6 olevaa lukua, joka nyt = 0002 lukuun SS:3FF0 001B 0001. SS:3FF2 0002 SS:3FF4 ???? SS:3FF6 3FFC SS:3FF8 0039 SS:3FFA 0003 SS:3FFC 0000 17) 000A JG PROGRAM.6 (0013) SP SS:3FEC ???? Taas [BP+04] > 0001, joten hyp„t„„n. BP SS:3FEE 3FF6 SS:3FF0 001B SS:3FF2 0002 SS:3FF4 ???? SS:3FF6 3FFC SS:3FF8 0039 SS:3FFA 0003 SS:3FFC 0000 18) 0013 MOV AX,[BP+04] SP SS:3FEC ???? Otetaan AX:„„n parametrin„ saatu luku... BP SS:3FEE 3FF6 SS:3FF0 001B SS:3FF2 0002 SS:3FF4 ???? SS:3FF6 3FFC SS:3FF8 0039 SS:3FFA 0003 SS:3FFC 0000 19) 0016 DEC AX SP SS:3FEC ???? ... v„hennet„„n sit„ yhdell„.... BP SS:3FEE 3FF6 SS:3FF0 001B SS:3FF2 0002 SS:3FF4 ???? SS:3FF6 3FFC SS:3FF8 0039 SS:3FFA 0003 SS:3FFC 0000 20) 0017 PUSH AX ... talletetaan se pinoon... SP SS:3FEA 0001 SS:3FEC ???? BP SS:3FEE 3FF6 SS:3FF0 001B SS:3FF2 0002 SS:3FF4 ???? SS:3FF6 3FFC SS:3FF8 0039 SS:3FFA 0003 SS:3FFC 0000 21) 0018 CALL PROGRAM.KERTOMA ... ja suoritetaan uusi rekursiivinen SP SS:3FE8 001B aliohjelmakutsu. SS:3FEA 0001 SS:3FEC ???? BP SS:3FEE 3FF6 SS:3FF0 001B SS:3FF2 0002 SS:3FF4 ???? SS:3FF6 3FFC SS:3FF8 0039 SS:3FFA 0003 SS:3FFC 0000 22) 0000 PUSH BP Talletetaan BP kuten aina aliohjelman SP SS:3FE6 3FEE alussa. SS:3FE8 001B Vertaa kohdat 4 ja 13 SS:3FEA 0001 SS:3FEC ???? BP SS:3FEE 3FF6 SS:3FF0 001B SS:3FF2 0002 SS:3FF4 ???? SS:3FF6 3FFC SS:3FF8 0039 SS:3FFA 0003 SS:3FFC 0000 23) 0001 MOVE BP,SP Toinen alkurutiini, kuten 5 ja 14 BP SP SS:3FE6 3FEE SS:3FE8 001B SS:3FEA 0001 SS:3FEC ???? SS:3FEE 3FF6 SS:3FF0 001B SS:3FF2 0002 SS:3FF4 ???? SS:3FF6 3FFC SS:3FF8 0039 SS:3FFA 0003 SS:3FFC 0000 24) 0003 SUB SP,0002 SP SS:3FE4 ???? Tehd„„n taas "tilaa" pinon p„„lle. BP SS:3FE6 3FEE SS:3FE8 001B SS:3FEA 0001 SS:3FEC ???? SS:3FEE 3FF6 SS:3FF0 001B SS:3FF2 0002 SS:3FF4 ???? SS:3FF6 3FFC SS:3FF8 0039 SS:3FFA 0003 SS:3FFC 0000 25) 0006 CMP WORD PTR [BP+04],0001 000A JG PROGRAM.6 (0013) SP SS:3FE4 ???? BP SS:3FE6 3FEE Suoritetaan kaksi k„sky„, jotka eiv„t SS:3FE8 001B muuta pinoa. Nyt paikassa BP+04 oleva SS:3FEA 0001 luku = 0001, joka ei ole suurempi SS:3FEC ???? kuin 0001, joten ei hyp„t„ vaan suoritus SS:3FEE 3FF6 jatkuu seuraavasta k„skyst„! SS:3FF0 001B SS:3FF2 0002 SS:3FF4 ???? SS:3FF6 3FFC SS:3FF8 0039 SS:3FFA 0003 SS:3FFC 0000 26) 000C MOV WORD PTR [BP-02],0001 Sijoitetaan paikkaan BP-02 luku 0001. SP SS:3FE4 0001 Nyt pinon p„„lle varattu tila tuli BP SS:3FE6 3FEE k„ytt””n!!! SS:3FE8 001B SS:3FEA 0001 SS:3FEC ???? SS:3FEE 3FF6 0011 JMP PROG.7 (0021) SS:3FF0 001B Jatketaan ohjelman suoritusta kohdasta SS:3FF2 0002 0021. SS:3FF4 ???? SS:3FF6 3FFC SS:3FF8 0039 0021 MOV AX,[BP-02] SS:3FFA 0003 Siirret„„n AX-rekisteriin muistipaikkaan SS:3FFC 0000 BP-02 talletettu luku eli funktion se arvo, jonka funktio palauttaa = 0001 27) 0024 MOV SP,BP Pino-osoittimeen siirret„„n Base Pointterin BP SP SS:3FE6 3FEE arvo. HUOMAA: Pinon p„„lle varattu tila SS:3FE8 001B "katosi". SS:3FEA 0001 SS:3FEC ???? SS:3FEE 3FF6 SS:3FF0 001B SS:3FF2 0002 SS:3FF4 ???? SS:3FF6 3FFC SS:3FF8 0039 SS:3FFA 0003 SS:3FFC 0000 28) 0026 POP BP Base Pointterille palautetaan kohdassa 22 pinoon talletettu arvo. Samalla tietysti SP SS:3FE8 001B pino-osoitin muuttui! SS:3FEA 0001 SS:3FEC ???? BP SS:3FEE 3FF6 SS:3FF0 001B SS:3FF2 0002 SS:3FF4 ???? SS:3FF6 3FFC SS:3FF8 0039 SS:3FFA 0003 SS:3FFC 0000 29) 0027 RET 0002 RET-k„sky ottaa pinon p„„lt„ paluuosoitteen, eli suoritus jatkuu osoitteesta 001B, 0002 aiheuttaa sen, ett„ pinosta poistetaan kaksi SP SS:3FEC ???? seuraavaa tavua = 00 01 = 0001, joita BP SS:3FEE 3FF6 k„ytettiin v„litt„m„„n aliohjelmalle SS:3FF0 001B parametri. SS:3FF2 0002 AX:ss„ palautuu siis arvo 0001 SS:3FF4 ???? SS:3FF6 3FFC SS:3FF8 0039 SS:3FFA 0003 SS:3FFC 0000 30) 001B IMUL WORD PTR [BP+04] Suoritetaan operaatio kertoma(n-1)*n: AX:ss„ on kertoma(n-1):n palauttama arvo (=0001) pinon muistipaikassa BP+04 on n (=0002). Tulos tulee AX-rekisteriin. (Suorituksen j„lkeen AX=0002) 31) 001E MOV [BP-02],AX Siirret„„n kertolaskun tulos pinon p„„ll„ SP SS:3FEC 0002 olevaan muistipaikkaan. BP SS:3FEE 3FF6 SS:3FF0 001B SS:3FF2 0002 0021 MOV AX,[BP-02] SS:3FF4 ???? Siirret„„n pinoon "s„il”tty" kertolaskun SS:3FF6 3FFC tulos palautettavaksi AX-rekisteriin. SS:3FF8 0039 SS:3FFA 0003 HUOMAUTUS: K„„nt„j„ ei voinut tiet„„, ett„ SS:3FFC 0000 aina ennen vastauksen palautusta suoritetaan kertolasku, jolloin palautettava vastaus on jo valmiina AX-rekisteriss„. T„st„ syyst„ eo. kaksi "turhan" tuntuista operaatiota! Esimerkiksi jos joku laskutoimitus palauttaisi vastauksen DX-rekisteriss„, teht„isiin MOV [BP-02],DX ja MOV AX,[BP-02]. 32) 0024 MOV SP,BP Otetaan kohdassa 31 k„ytetty "s„il”", BP SP SS:3FEE 3FF6 pinon p„„ll„ oleva muistipaikka, pois SS:3FF0 001B pinosta, kuten kohdassa 27. SS:3FF2 0002 SS:3FF4 ???? SS:3FF6 3FFC SS:3FF8 0039 SS:3FFA 0003 SS:3FFC 0000 33) 0026 POP BP Otetaan pinosta Base Pointterille kohdassa 13 pinoon talletettu arvo. Pino-osoitin SP SS:3FF0 001B muuttuu vastaavasti. SS:3FF2 0002 SS:3FF4 ???? BP SS:3FF6 3FFC SS:3FF8 0039 SS:3FFA 0003 SS:3FFC 0000 34) 0027 RET 0002 Palataan aliohjelmasta edelliselle tasolle SP SS:3FF4 ???? kuten kohdassa 29. BP SS:3FF6 3FFC AX palauttaa arvon 0002. SS:3FF8 0039 SS:3FFA 0003 SS:3FFC 0000 35) 001B IMUL WORD PTR [BP+04] AX:ss„ oli 0002, [BP+04] = 0003. Siis SP SS:3FF4 ???? suorituksen j„lkeen AX=0006 BP SS:3FF6 3FFC SS:3FF8 0039 SS:3FFA 0003 SS:3FFC 0000 36) 001E MOV [BP-02],AX SP SS:3FF4 0006 0021 MOV AX,[BP-02] BP SS:3FF6 3FFC SS:3FF8 0039 Suoritetaan sama "turha" toimenpide SS:3FFA 0003 kuin kohdassa 31. SS:3FFC 0000 37) 0024 MOV SP,BP BP SP SS:3FF6 3FFC Kuten kohdissa 27 ja 32..... SS:3FF8 0039 SS:3FFA 0003 SS:3FFC 0000 38) 0026 POP BP Otetaan kohdassa 4 talletettu Base SP SS:3FF8 0039 Pointterin arvo takaisin. SS:3FFA 0003 BP SS:3FFC 0000 39) 0027 RET 0002 Suoritetaan paluu aliohjelmasta: BP SP SS:3FFC 0000 Nyt palataan osoitteeseen 0039! Rekursiivinen aliohjelma on saatu suoritetuksi ja pino on t„sm„lleen samassa tilassa kuin ennen ensimm„sita aliohjelmakutsua. Kaikki on siis kunnossa!