Les 5: Ons eerste programma. In de vorige les hebben we het gehad over de syntax van de assembleertaal voor de 68000 en hoe een gecodeerde instructie er nou uitziet. Vandaag wil ik voordat we ons op de afzonderlijk instructies storten eerst eens een klein assemblerprogrammaatje demonstreren om een beetje de smaak ervan te pakken te krijgen, en om te zien hoe de assembler werkt. Het is dus NIET de bedoeling om uit te leggen hoe het programma werkt, hoewel je je daar onwillekeurig toch wel een soort idee over zult vormen bij het doorlezen of intypen, maar om te demonstreren hoe onze assembler werkt. Het is waarschijnlijk het handigst om de hiernavolgende sourcecode electronisch 'uit te knippen' en ONGEWIJZIGD aan de assembler te voeren, om typfouten te vermijden. Aan de andere kant leren degenen die zelf typen sneller hoe deze assembler zijn input graag heeft... Kies zelf maar. Ik geef het programma met zoveel commentaar als ik zinvol acht in dit stadium. Later zullen we al deze instructies afzonderlijk echt heel erg uitgebreid gaan bekijken. Het is traditie dat het eerste programma dat je in een nieuwe taal schrijft dient om de woorden 'Hello, world!' op het scherm te toveren, en dat is dan ook precies wat dit programma doet. Voor de zelftypers: Deze assembler is EXTREEM kieskeurig met zijn input. Ik heb zelf de volgende restricties opgespoord, die niet allemaal in de handleiding staan: - Er mogen geen regels van meer dan 72 tekens in voorkomen; dat leidt tot volledig onvoorspelbaar gedrag. - Er mogen geen tabs in de input voorkomen; dat brengt de editor volledig in de war. - Er mag geen commentaar staan achter een dc.x statement, dat wordt opgevat als een onbekend label. - Labels moeten op de eerste positie van een regel beginnen; - Instructies liefst met 1 spatie ervoor, maar nooit helemaal zonder. - dc.b statements zonder .even erachteraan leiden tot een crash zonder vorm van proces als de volgende instructie daardoor op een oneven adres terechtkomt. - Ook moet er 1 spatie tussen de instructie en de operand(en) , en evt. meer spaties voor het commentaar. Het programma maakt hier bij het listen wel wat moois van. - Verder is het noodzakelijk om lege regels aan het eind van het programma te verwijderen. Het programma (ook los in de .arc versie van deze les als hello.asm): ******************************************************************* * * -- Hello, World! V 0.0 dd 22-06-88 -- * * Demonstratieprogramma voor het gebruik van 68000 assembleertaal * * Geschreven door E. van Herk voor de cursus 68000 assembler op * BBS Mega-net, 1988 * * Machine: Atari ST, elk type. * * Dit programma wordt zonder wijzigingen door de cursus-assembler * geaccepteerd. * * Prog verwacht: een geldige stack. * * Doel: het printen van de woorden 'Hello, World!' op het scherm, en * met een toetsdruk eindigen. * * ( Commentaar dient om de lezer te vertellen hoe het programma heet, * wat het versienummer is, wie het heeft geschreven, op welke comp. * het moet draaien (kleur? zwart-wit? geheugengebruik?), met welk * programma het kan worden vertaald, wat het precies doet, wat het * verwacht als het opgestart wordt en wat het teruglevert. ) * * ***************************************************************** * * Hello, World program. * start bsr cls ; wis het scherm schoon lea string(pc),a0 ; zet het adres van onze string in a0 bsr puts ; druk de string af bsr getkey ; wacht op een toetsdruk bra exit ; en verlaat het programma. * * en de data voor ons prog zijn... * string dc.b "Hello, World!",0 .even ; volgende instructie op even adres. * * *************** Beginners dit stuk niet lezen! ********************* * * Modules nodig voor hello, world program. * * Conventies: * Registers d0,d1,a0,a1 worden gebruikt voor parameterovergave. Deze * registers worden niet gered door de aangeroepen modules. Alle andere * registers worden gegarandeerd niet veranderd. * * parameterovergave: pointers in a0 en a1, andere in d0 en d1. * * Module cls (clear screen), wist het scherm schoon en zet de cursor i * de linker bovenhoek. * cls lea clstr(pc),a0 ; adres van clear screen string bsr puts ; zend die string naar het scherm rts ; en klaar! * en weer de data.. clstr dc.b 27,'E',0 .even * * deze routine maakt gebruik van de VT-52 emulator van de Atari, als j * de tekens escape E naar het scherm stuurt wordt dat gewist. * * Module puts: (put string) schrijft een string waarvan het adres in A * staat naar het scherm. * puts move.b (a0)+,d0 ; haal eerste letter beq.s done ; als letter = $00 zijn we klaar move.l a0,-(a7) ; red onze pointer bsr putc ; schrijf die letter naar het scherm move.l (a7)+,a0 ; haal pointer terug bra.s puts ; en doe dat nog eens done rts ; en terug naar waar we vandaan kwamen. * * Module putc: (put character) schrijft een letter in de lage byte van * d0 naar het scherm. * putc movem.l d2/d3/a2/a3,-(a7) ; save registers and.w #$FF,d0 ; clear hi byte van d0 move.w d0,-(a7) ; letter move.w #2,-(a7) ; functienummer trap #1 ; aanroep van Gemdos addq.l #4,a7 ; zet stack weer goed movem.l (a7)+,d2/d3/a2/a3 ; restore registers rts * * * Module getkey: wacht op een toetsdruk en geeft die terug in d0. * lage byte bevat letter, lage byte van het hoge woord bevat scancode. * getkey movem.l d2/d3/a2/a3,-(a7) ; save registers move.w #1,-(a7) ; conin functie trap #1 ; call gemdos addq.l #2,a7 ; zet stack weer goed movem.l (a7)+,d2/d3/a2/a3 ; restore registers rts * * Module exit: verlaat programma * exit clr.w -(a7) ; no error move.w #$4c,-(a7) ; functienummer trap #1 ; hoepla! eruit. .DATA .BSS * * ************** OK beginners, kijk maar weer! ********************** Hoe vertalen we deze source naar een programma: (Ik neem aan dat je de source als hello.asm op schijf hebt staan.) <3 x return> ( de prompt > verschijnt) load hello.asm ( laad het prog in het geheugen) l ( we zien een tamelijk nette listing) prgasm f ( assembleer een uitvoerbaar prog) prgsave hello.prg ( en save het resultaat) quit ( het programma vraagt 'are you sure?') y ( we are sure) klik nu op hello.prg en bewonder het resultaat! Over het programma: je ziet dat ik de taak die we willen uitvoeren in sub- taken heb opgesplitst. Het isoleren van goede subtaken is een kunst, de belangrijkste deskundigheid van de programmeur. Een goede subtaak vormt een conceptuele eenheid en kan eventueel later ook voor andere programma's worden gebruikt, dat spaart je dan weer werk. De gebruikelijke naam voor subtaak is subroutine. De eerste subtaak is het wissen van het scherm. Die bestaat weer uit twee subtaken: het laden van de bevelstring voor die functie van het operating system in a0, en het naar het beeldscherm sturen ervan met de puts functie. Het laden van een adres in a0 is een taak die zo simpel is dat de computer het met een instructie uit kan voeren. Voor de tweede subtaak puts hebben we een nieuwe subtaak nodig, putc. Die stuurt steeds een teken naar het scherm. De functie putc bestaat zelf weer uit honderden machinecode instructies, maar die zien we niet omdat het operating system ze voor ons uitvoert. Een schema van de nivo's in ons programma: programma clear screen print string print letter ( operating system ) print string print letter ( operating system ) wacht toets ( operating system ) exit ( operating system ) We zien dat het operating system eigenlijk aan de basis van alle in - en uitvoer staat. De puts routine, print string, wordt twee keer aangeroepen, vanaf twee verschillende nivo's. Het leuke van dit soort routines is dat ze overal en altijd bruikbaar zijn. Je hoeft niet te weten hoe ze werken, maar alleen wat ze doen. Voor deze cursus hanteer ik de volgende principes: 1) Alle 'black box' subroutines halen hun inputdata uit een of meer van de registers a0,a1,d0,d1; 2) Deze registers mogen worden veranderd door de subroutines, na een aanroep weet je dus niet wat er in deze registers zal staan, behalve als ze een resultaat teruggeven, dat staat dan in d0 of a0. 3) Alle andere registers worden gegarandeerd niet veranderd. Verder worden getallen in d0 en/of d1 doorgegeven, en adressen in de registers a0 en/of a1. Welke registers worden gebruikt moet per routine worden gespecificeerd. Dat was het dan weer voor wat betreft deze les. Ik hoop dat jullie niet geschrokken zijn van dit alles, het is zoals gezegd een smaakmakertje, dat ik heb ingevoegd omdat ik, de volgende zes lessen overziend, ze erg droog en theoretisch vond voor wie nog niets gezien heeft van wat je er nou mee kunt doen!