elomax

[ Techniek ] [ Shop ] [ Site map
[ Assembler ] Programmeren ] Foutmeldingen ]

Terug
Omhoog

De Assembler

Als u eenmaal een programma hebt geschreven in een editor window, dan is het moment daar om dit programma te laten vertalen naar de codes die de micro-controller begrijpt. Het programma dat deze vertaling voor zijn rekening neemt heet de assembler.

De assembler vertaalt de programmatekst naar de machinecodes die de processor op de SIMPLEX als instructies kan herkennen. Zo kan de assembler de tekst

LDAA #10

herkennen, en vertalen naar de code voor deze instructie:

$86
$0A

Tijdens het assembleren maakt de assembler een file aan, waarin deze codes worden opgeslagen. Deze file bevat informatie betreffende de inhoud die in het programmageheugen op de SIMPLEX moet worden gezet. Deze informatie bestaat uit:

  • adressen

  • data

Intern houdt de assembler een datagebied bij, dat een afspiegeling is van het programmageheugen van de micro-controller. In dit datagebied worden de gevonden codes geplaatst, en later wordt de inhoud van dit datagebied in een file gezet. Deze file wordt bij het 'downloaden' gebruikt om het programmageheugen van de micro-controller te programmeren.

De instructiepointer

De assembler heeft intern een instructie-'pointer' (wijzer), die door de assembler gebruikt wordt om aan te wijzen op welke plaats in het programmageheugen van de micro-controller, de vertaalde codes geplaatst moeten worden. Deze pointer moet bij het begin van het assembleren natuurlijk worden geladen met het beginadres van het programma, zodat de assembler weet op welke plaats de programmacode terecht moet komen. De assembler heeft een apart symbool voor de instructiepointer:

'$' betekent de instructiepointer.

Overal waar de assembler het alleenstaande '$'-symbool tegenkomt zal hij de huidige waarde van de instructiepointer invullen.

Pseudo-instructies

De instructiepointer kan gemanipuleerd worden door middel van instructies die alleen door de assembler gebruikt worden tijdens het assembleren. Deze instructies moeten onderscheiden worden van de instructies in het programma die uiteindelijk door de micro-controller moeten worden uitgevoerd. Instructies die voor de assembler bestemd zijn, en dus het assembleer proces beïnvloeden, noemt men 'pseudo-instructies' of ook wel 'directives'. De assembler kent verschillende van dit soort pseudo-instructies.

END

Een simpel voorbeeld van een pseudo-instructie is 'end'. Dit geeft de assembler te kennen, dat het eind van de programmatekst bereikt is. De assembler zal tekst die na de 'end' instructie komt niet vertalen. De 'end' instructie levert geen code voor de micro-controller op, maar is alleen voor de besturing van de assembler bedoeld.

Manipulatie van de instructiepointer

De instructiepointer bevat het adres waar de assembler de geassembleerde codes plaatst. De instructiepointer kan worden geladen door middel van de 'org' pseudo-instructie.

ORG (origin)

Met deze pseudoinstructie wordt de instructiepointer geladen. Bijvoorbeeld:

ORG $B600

Hiermee wordt de waarde $B600 in de instructiepointer geladen, zodat alle bytes die de assembler vervolgens aanmaakt vanaf adres $B600 zullen worden opgeslagen.

Rekenen met de instructiepointer

De assembler laat ook toe berekeningen op de instructiepointer uit te voeren. De waarde die de instructiepointer op elk moment heeft, kan worden opgevraagd via het symbool '$'. Wanneer dit symbool in een formule voorkomt, vult de assembler hiervoor de huidige waarde van de instructiepointer in.
Bijvoorbeeld:

ORG $+3

Hiermee wordt de instructiepointer geladen met de waarde van de instructiepointer + 3. Effectief betekent dit derhalve, dat de assembler 3 bytes zal overslaan bij het vullen van het geheugen.

PAGE: pagina selectie

In het geheugengebied van de SIMPLEX is het deel tussen $4000 en $7FFF gereserveerd voor acht gelijke pagina's van elk $4000 bytes groot. Afhankelijk van de waarde die in het pagina register wordt gezet, zal één van deze acht pagina's geselecteerd zijn en in de geheugenmap zichtbaar. De andere zeven zijn dan niet bereikbaar. U kunt in de assembler opgeven in welk van deze acht pagina's de code gezet moet worden. Standaard zal dat op pagina 0 zijn, en dat is ook de pagina die na reset actief is. Als u de verschillende pagina's niet gebruikt, hoeft u dus niets te doen. Als u  code in een van de andere pagina's wilt zetten, dan kunt u de assembler vertellen dat de volgende code naar een andere pagina moet. De pseudoinstructie hiervoor is PAGE. Bijvoorbeeld:

PAGE 2

Hiermee vertelt u de assembler dat alle volgende code in pagina twee gezet moet worden. Hou er rekening mee dat de instructiepointer gewoon doorgaat waar hij gebleven was. In de meeste gevallen zult u dan ook voor elke pagina een eigen instructiepointer gebruiken. Bijvoorbeeld:

program		SPACE
		ORG $8000
		ldab #2		|selecteer pagina twee
		stab pageselect
		ldx #$4000	|wijs naar begin van de pagina
		PAGE 2		|zet een tabel in pagina twee
page2		SPACE
		ORG $4000	|de pagina begint op $4000
		fcb 1,4,2,3,5	|de tabel

		PAGE 0		|ga weer verder met code in pagina 0 te zetten
program		SPACE		|en wel op de plaats waar we gebleven waren

Bytes in het geheugen reserveren

RMB (reserve memory byte)

Een andere manier om een aantal bytes in het geheugen over te slaan, is de pseudo-instructie 'RMB'. Met deze instructie kunnen een aantal bytes in het geheugen gereserveerd worden.
Bijvoorbeeld:

RMB 3

Hiermee wordt de instructiepointer met 3 verhoogd. Er ontstaan 3 niet-ingevulde plaatsen in het geheugen.

Programma- en dataruimte

Het heeft natuurlijk weinig zin om stukken in het programmageheugen over te slaan en ongebruikt te laten. Anders wordt het, wanneer u de pointer op het datageheugen laat wijzen. U kunt dan bytes in het datageheugen reserveren voor de variabelen die u in uw programma gaat gebruiken. U hoeft niet zelf te tellen hoeveel bytes uit het datageheugen u al gebruikt heeft, en het adres van de volgende variabele uit te rekenen. U begint met een pointer naar het datageheugen, en gebruikt dan vervolgens voor elke variabele die u definiëert de RMB pseudo-instructie om een aantal bytes voor de variabele te reserveren in het datageheugen. Eigenlijk heeft u dus twee pointers nodig:

- een pointer in het programmageheugen

- een pointer in het datageheugen

SPACE

De assembler laat toe zoveel pointers te definiëren als u denkt nodig te hebben. Een pointer wordt gedefiniëerd met behulp van de SPACE pseudo-instructie. Elke pointer die u op deze wijze aanmaakt, kunt u een naam geven.
Bijvoorbeeld:

PROGRAM space
org $B600

DATA space
org $0000

Er wordt eerst een pointer gedefiniëerd met de naam 'PROGRAM', en deze pointer wordt geïnitialiseerd op $B600. Daarna wordt een pointer met de naam 'DATA' aangemaakt, en geladen met de waarde $0000.

U kunt nu naar believen wisselen tussen deze twee pointers.
Bijvoorbeeld:

* demonstreer het gebruik van SPACEs

PROGRAM space   |een pointer voor de code
org $B600       |beginnen op $B600

DATA space      |een pointer voor de data
org $0000       |beginnen op $0000


PROGRAM space   |activeer de PROGRAM pointer
ldaa #10        |maak code aan
ldab #20
aba


DATA space      |activeer de DATA pointer
rmb 1           |reserveer 1 byte
rmb 10          |reserveer 10 bytes

end             |einde programma

Eerst worden de PROGRAM- en de DATA- pointer gedefiniëerd en geladen. Daarna wordt de PROGRAM pointer geactiveerd. De instructies die hierna volgen worden door de assembler vertaald naar de bijbehorende codes, en geplaatst op het adres dat door de actieve pointer (in dit geval dus de PROGRAM pointer) wordt aangewezen. Daarna wordt de DATA pointer geactiveerd, en in het data-gebied wordt een aantal variabelen gereserveerd (één van 1 byte, en één van 10 bytes lang.)

Commentaar

In het voorbeeld kunt u tevens zien dat in de programmatekst commentaar kan worden opgenomen. Commentaar is erg belangrijk wanneer u later nog eens een programma wilt veranderen. In het commentaar kunt u vertellen hoe het programma werkt, en dat helpt wanneer u een programma moet lezen en begrijpen. Probeer commentaar kort en 'to-the-point' te houden. Commentaar scheidt u van de programmatekst door een '*' of een '|':

  • Een regel die begint met '*' wordt door de assembler als commentaar opgevat.
  • Als de assembler een '|' tegenkomt, wordt de rest van de regel als commentaar opgevat.

Listing

Het gebruik van 'spaces' wordt misschien duidelijker wanneer de assembler laat zien wat er precies gebeurd is. Hiertoe kunt u de assembler een 'listing' laten maken. Hierin komt te staan wat de assembler voor code aangemaakt heeft. Typt u hiertoe het bovenstaande voorbeeld eens in, in een editwindow. U bewaart de tekst in een file op uw schijf (onder 'File' kiest u voor 'Save as...', en vervolgens geeft u de naam die de file moet krijgen.) Daarna kiest u 'Assembleren' onder de hoofdkeuze 'Run'. Selecteer een 'listing to screen'. Als u geen typfouten gemaakt heeft, krijgt u de volgende listing:

Page: 1
Simplex package release 2.2 .......
File: C:\SPACES.ASM Friday 27﷓8﷓2003 at 17:7:13

0000 * demonstreer het gebruik van SPACEs
0000 
0000 PROGRAM space                 |een pointer voor de code
0000 org $B600                     |beginnen op $B600
B600 
B600 DATA space                    |een pointer voor de data
0000 org $0000                     |beginnen op $0000
0000 
0000 
0000 PROGRAM space                 |activeer de PROGRAM pointer
B600 860A ldaa #10                 |maak code aan
B602 C614 ldab #20
B604 1B aba
B605 
B605 
B605 DATA space                    |activeer de DATA pointer
0000 rmb 1                         |reserveer 1 byte
0001 rmb 10                        |reserveer 10 bytes
000B 
000B > 0000 end                    |einde programma

0 Error(s).

De listing begint met een kop met pagina-nummer. In de kop staat ook aangegeven dat de file met de assembler uit het simplex-programma gemaakt is, de naam van de file die de oorspronkelijke tekst van het programma bevat, en datum en tijd waarop de file geassembleerd werd.

De linker kolom van de listing geeft adressen weer (in hexadecimale notatie.) Rechts hiervan staan de codes die de assembler op deze adressen heeft ingevuld (ook weer in hex.) Niet op alle adressen worden codes ingevuld. Weer rechts hiervan staat de programmatekst.

Het adres (de linker kolom) geeft steeds de inhoud van de 'huidige' pointer. Bovenaan is er nog geen pointer gedefiniëerd. De assembler gebruikt dan een default pointer, die aan het begin de waarde $0000 heeft. Deze default pointer heeft geen eigen naam.

Als een nieuwe pointer gedefiniëerd wordt, krijgt deze onmiddellijk de waarde $0000. Als de pointer op een andere waarde moet beginnen, dient u een 'org' pseudo-instructie te gebruiken zoals ook in bovenstaand programma gebeurt.

Nadat de PROGRAM pointer gedefiniëerd en geladen is, wordt deze automatisch als de huidige pointer genomen. Aan de linkerkant ziet u de waarde van deze pointer verschijnen ($B600.) Op dezelfde manier kunt u zien hoe de DATA pointer ontstaat.

Op het moment dat de PROGRAM pointer weer geactiveerd wordt, verschijnt aan de linkerkant weer de inhoud van deze pointer. De instructies die hieronder staan leveren code op. De assembler heeft van de instructie ldaa #10 twee bytes gemaakt: $86 en $0A. Nadat deze twee bytes zijn ingevuld op adres $B600 en adres $B601, is de PROGRAM pointer met twee verhoogd, en heeft de waarde $B602 gekregen. Zo worden ook de andere instructies vertaald en ingevuld.

Op het moment dat de DATA pointer weer actief wordt gemaakt, zet de assembler de waarde van de DATA pointer aan de linkerkant. Hier kunt u zien dat de pseudo-instructie 'rmb 1' geen code oplevert, maar wel de pointer met 1 verhoogt. Na 'rmb 10' zijn er in totaal 11 bytes gereserveerd, en staat de DATA pointer dus op 11 ($0B.) De gereserveerde bytes staan op adres 0 t/m 10, het eerste vrij byte bevindt zich op adres 11.

Labels

Wanneer u de bovenbeschreven methode toepast om variabelen in het datageheugen te reserveren, rekent de assembler, zoals uit de listing blijkt, automatisch de adressen van de variabelen uit. U moet de variabelen natuurlijk ook in de rest van uw programma kunnen gebruiken. Daartoe moet u ze kunnen adresseren, dus in feite moet u weten op welk adres in het datageheugen de variabelen terecht zijn gekomen. Deze adressen worden door de assembler uitgerekend, dus u kunt het rustig aan de assembler overlaten om bij te houden op welk adres een variabele precies terecht komt.

Om een adres later in het programma te kunnen gebruiken, kunt u een naam toekennen aan een adres. Wanneer een adres een naam krijgt, noemt men deze naam een 'label'.
Een voorbeeld:

* Labels toekennen aan een adres

PROGRAM space
org $B600

DATA space
org $0000


DATA space    |variabelen

teller1 rmb 1 |1 byte op adres 'teller1'
teller2 rmb 1 |1 byte op adres 'teller2'


PROGRAM space |programma code
ldab teller1
addb #1
stab teller1

inc teller2

end

In het datagebied wordt 1 byte gereserveerd voor een teller. Het adres van dit byte krijgt de naam 'teller1'. Zo wordt ook een tweede variabele benoemd (teller2.) Het is nu mogelijk in het programma niet direct het adres van 'teller1' of 'teller2' te gebruiken, maar hier indirect (via de naam) naar te verwijzen. De assembler weet de werkelijke waarde van de adressen van 'teller1' en 'teller2', en zal deze waarde correct invullen als naar deze adressen verwezen wordt.

Typt U het bovenstaande programma eens in, bewaar de ingetypte tekst in een file, en start de assembler. De listing laat zien dat voor de adressen de juiste waarden worden ingevuld door de assembler.

Page: 1
Simplex package release 2.2 .......
File: C:\LABELS.ASM Friday 27﷓8﷓2003 at 17:50:51

0000 * Labels toekennen aan een adres
0000 
0000 PROGRAM space
0000 org $B600
B600 
B600 DATA space
0000 org $0000
0000 
0000 
0000 DATA space |variabelen
0000 
0000 teller1 rmb 1 |1 byte op adres 'teller1'
0001 teller2 rmb 1 |1 byte op adres 'teller2'
0002 
0002 
0002 PROGRAM space |programma code
B600 D600 ldab teller1
B602 CB01 addb #1
B604 D700 stab teller1
B606 
B606 7C0001 inc teller2
B609 
B609 > 0000 end

0 Error(s).

Voor de instructie 'ldab teller1' heeft de assembler de code $D6 $00 ingevuld. Teller1 staat op adres $0000, en dit adres kan via 'direct' adressering worden opgegeven. De code $D6 is de code voor 'ldab' (met direct adressering), en $00 is het adres van 'teller1'.

De instructie 'inc' kent geen 'direct' adressering, alleen 'extended' adressering. Hier kan de assembler de compacte adressering niet toepassen, en vult voor het adres $0001 in (de code voor 'inc' is $7C.) Dit klopt ook, het adres van 'teller2' is inderdaad $0001.

De naam die u aan een adres toekent (label) mag 128 tekens lang zijn. De assembler zal echter alleen gebruik maken van de eerste 32 tekens van de naam.

Labels mogen letters, cijfers, of de speciale tekens _$@ bevatten, maar mogen niet met een cijfer beginnen.

Labels kunnen in hoofdletters of kleine letters staan, de assembler maakt hier geen onderscheid in.

De naam mag niet overeenkomen met een woord dat de assembler al kent (bijvoorbeeld de naam van een instructie of een pseudo-instructie.)


Labels en BRANCH instructies

Met een BRANCH instructie zoals BEQ, BNE, BLO, etc.. kan de program-counter een aantal bytes 'verschoven' worden. Zie ook de beschrijving van deze instructies in de instructie-set.

Het aantal bytes dat de program-counter verschoven moet worden, wordt in de instructie opgegeven als een 'offset'. De assembler kan de gewenste offset automatisch uitrekenen. Hiertoe geeft u het adres waar naartoe gesprongen moet worden een naam (label.) Hierna kunt u in de BRANCH instructie gewoon dit label gebruiken. De assembler weet dat het adres waar naartoe moet worden gesprongen, omgerekend moet worden naar een offset ten opzichte van het adres van de BRANCH instructie, en rekent de offset automatisch uit. Wanneer de offset te groot of te klein wordt (dus wanneer de sprong te groot is), geeft de assembler een foutmelding.
Een voorbeeld:

.......
.......
ldab #6
ldaa #1
herhaal lsla
decb
bne herhaal
.......
.......

In dit voorbeeld wordt accumulator A naar links geschoven en accumulator B wordt met één verlaagd. Dit wordt herhaald totdat accumulator B nul bevat.

Constanten

Wanneer u een naam aan een adres toekent, zal de assembler steeds wanneer hij deze naam tegenkomt, hiervoor de waarde van het adres invullen. Op dezelfde wijze is het mogelijk elke willekeurige constante een naam te geven. Dit kan met behulp van de pseudo-instructie

EQU

Equ is de afkorting voor 'equate'. Hiermee geeft u een constante een naam.
Bijvoorbeeld:

gewenst_aantal equ 60

Overal waar u in het programma nu 'gewenst_aantal' typt, zal de assembler op die plaats 60 invullen. Door constanten een goed gekozen naam te geven kunt u de leesbaarheid en begrijpelijkheid van een programma aanzienlijk verbeteren.

De naam die u aan een constante toekent mag 128 tekens lang zijn. De assembler zal echter alleen onderscheid maken in de eerste 32 tekens van de naam.

De naam mag letters, cijfers, of de speciale tekens _$@ bevatten, maar mag niet met een cijfer beginnen.

De naam mag in hoofdletters of kleine letters staan, de assembler maakt hier geen onderscheid in.

De naam mag niet overeenkomen met een woord dat de assembler al kent (bijvoorbeeld de naam van een instructie of een pseudo-instructie.)

De assembler heeft een aantal 'ingebouwde' constanten:

bit0 = 1 (%0000000000000001)
bit1 = 2 (%0000000000000010)
bit2 = 4 (%0000000000000100)
bit3 = 8 (%0000000000001000)
bit4 = 16 (%0000000000010000)
bit5 = 32 (%0000000000100000)
bit6 = 64 (%0000000001000000)
bit7 = 128 (%0000000010000000)
bit8 = 256 (%0000000100000000)
bit9 = 512 (%0000001000000000)
bit10 = 1024 (%0000010000000000)
bit11 = 2048 (%0000100000000000)
bit12 = 4096 (%0001000000000000)
bit13 = 8192 (%0010000000000000)
bit14 = 16384 (%0100000000000000)
bit15 = 32768 (%1000000000000000)



Rekenen in de assembler

De assembler kan tijdens het assembleren ook berekeningen voor u doen. Hierbij staan de volgende bewerkingen ter beschikking:

  • * - + / ( ) Rekenkundige operators

  • HIGH Alleen het meest significante byte van een 16-bits woord

  • LOW Alleen het minst significante byte van een 16-bits woord

  • NOT NOT operator

  • XOR XOR operator

  • OR OR operator

  • AND AND operator

  • SHL Naar links schuiven

  • SHR Naar rechts schuiven

  • DIV Integer deling

  • MOD Modulo operatie

De assembler rekent in 16-bits getallen.

Enkele voorbeelden van berekeningen zijn in het onderstaande programma gegeven. Door het in te voeren in een edit-window, de file te bewaren op disk, de assembler te starten en de listing te bekijken, kunt u zien wat de assembler in de verschillende gevallen uitgerekend heeft.

* voorbeelden van berekeningen door de assembler
DATA space
org $0000

PROGRAM space
org $B600


***********************************************************************
* vaste waarden toekennen aan constanten en berekeningen doen
***********************************************************************

* Geef label 'waarde1' de waarde 5
waarde1 equ 5

* en geef label 'waarde2' de waarde 7
waarde2 equ 7

* bereken nu de waarde die aan 'waarde3' toegekend wordt
waarde3 equ waarde1 + waarde2

* of voer een andere berekening uit:
waarde4 equ waarde1 * waarde2
waarde5 equ waarde1 * waarde1 * waarde2 / 10
waarde6 equ (waarde1 + waarde2) / 6

highbyte equ high($1234)
lowbyte equ low($1234)


bytes_per_record equ 5
aantal_records equ 18
DATA space
data_array rmb aantal_records * bytes_per_record


***********************************************************************
* logische bewerkingen
***********************************************************************

* definieer een bitpatroon
masker equ bit7 or bit6 or bit5

* inverteren
patroon1 equ not( masker)

* logische bewerkingen uitvoeren
patroon2 equ (( not(patroon1 and masker)) or bit4) xor bit1

end

Vaste getallen in het geheugen zetten

In het programmageheugen komen in ieder geval de codes voor de instructies van het programma terecht. Maar ook andere gegevens die bij starten van het programma bekend moeten zijn, kunnen natuurlijk in dit geheugen geplaatst worden. Denk bijvoorbeeld aan een opzoektabel, of aan vaste teksten. Om deze getallen in het geheugen te plaatsen kent de assembler de volgende pseudo-instructies:

  • FCB Byte-waarde(n) in het geheugen plaatsen

  • FDB 16-bits woord(en) in het geheugen plaatsen

  • FCC Vaste tekst in het geheugen plaatsen

FCB

De FCB (form constant byte) pseudo-instructie laat toe, één of meer bytes in het geheugen te plaatsen. Zo zal bijvoorbeeld de pseudo-instructie

FCB 1,2,3,$0A,%01000000

de bytes $01, $02, $03, $0A en $40 achtereenvolgens in het geheugen plaatsen. Het is ook mogelijk de ASCII-code van een teken als byte op te slaan. De code voor een 'A' kunt u bijvoorbeeld in het geheugen plaatsen met:

FCB 'A

Door de letter vooraf te laten gaan door het ' teken, vertaalt de assembler de letter eerst naar de bijbehorende ASCII code voor de letter.

FDB

De FDB (form double byte) pseudo-instructie laat toe, één of meer 16-bits getallen in het geheugen te plaatsen. Zo zal bijvoorbeeld de pseudo-instructie

FDB 1,2,3,$125A,'T

de 16-bits waarden $0001, $0002, $0003, $125A en $0054 achtereenvolgens in het geheugen plaatsen. Hierbij wordt eerst het meest significante byte opgeslagen, en daarna (op een adres dat 1 hoger is), het minst significante byte.

Het is ook mogelijk de ASCII-code van twee tekens als twee bytes op te slaan. De codes voor een 'A' en een 'T' kunt U bijvoorbeeld in het geheugen plaatsen met:

FDB 'AT

Door de letters vooraf te laten gaan door het ' teken, vertaalt de assembler de letters eerst naar de bijbehorende ASCII code voor de letters. Daarna worden de gevonden bytes in het geheugen geplaatst (het voorste teken het eerst.)

FCC

De FCC (form constant character) pseudo-instructie is bedoeld om tekst om te zetten naar de bijbehorende ASCII codes, en deze codes vervolgens achtereenvolgens in het geheugen te plaatsen. Tekst voert u in door de tekst tussen ' tekens te plaatsen. Zo zal bijvoorbeeld de pseudo-instructie

FCC 'tekst'

de ASCII codes voor de letters 't', 'e', 'k', 's', en 't' achtereenvolgens in het geheugen plaatsen.

Enkele voorbeelden hiervan zijn in het onderstaande programma gegeven. Door het in te voeren in de assembler en de listing te bekijken, kunt u weer zien wat voor code de assembler in de verschillende gevallen maakt.

De listing zal overigens niet altijd alle waarden laten zien die werden aangemaakt. Wanneer de lijst aangemaakte bytes te veel plaats zou innemen in de listing, wordt de lijst afgekort. U ziet dan alleen het begin.

***********************************************************************
* vaste getallen in het geheugen zetten
***********************************************************************

patroon2 equ %01001110
waarde1 equ 10245
waarde2 equ 234
waarde5 equ 1300

PROGRAM space
org $B600

* een byte, decimaal opgegeven
fcb 17

* een byte, opgegeven in binair
fcb %00000001

* een byte, opgegeven in hexadecimaal
fcb $2

* een karakter uit de ASCII set
fcb 'A'

* een eerder berekende waarde
fcb patroon2

* of een combinatie
fcb $AA, 17, 'A', 'B', %10001000, (patroon2 or bit5)

* of een reeks tekens uit de ASCII set
fcc 'Dit is een string'

* of een combinatie
fcc 'En dit ook', $0D, $0A, 0

* een 16﷓bits waarde in het geheugen zetten
fdb $1234

* of een eerder berekende 16-bits waarde in het geheugen zetten
fdb waarde5

* of meerdere 16-bits waarden in het geheugen zetten
fdb $1234, waarde1, 2 * waarde2, waarde5 / 4

end

Files inlezen

Binnen een programma kunnen andere files worden ingelezen. Dit gaat met behulp van de pseudo-instructie

INCL

De assembler is uitgevoerd met de mogelijkheid binnen een file te verwijzen naar een andere file. De file waar naar verwezen wordt, wordt bij assembleren door de assembler als geheel ingelezen op de plaats waar de 'incl' pseudo-instructie staat. Hiermee kunnen grotere programma's gemaakt worden, zonder dat de programma files onacceptabel groot worden.

Daarnaast kunnen stukken programma die in elk project gelijk zijn (zoals bijvoorbeeld de definitie van de geheugenmap), apart in een file gehouden worden. Overal waar u die file dan nodig heeft, kunt u die inlezen met een 'incl' pseudo-instructie. Dit zorgt voor beter leesbare en te onderhouden programma's.

Voor het inlezen van een andere file binnen een programma gebruikt u de 'incl' (van: include) opdracht aan de assembler. Achter de 'incl' opdracht wordt de naam van de in te lezen file opgegeven (tussen " tekens.) Deze naam mag compleet met volledig pad worden opgegeven, of alleen als filenaam. In het laatste geval zoekt de assembler de file in de huidige directory.
Bijvoorbeeld:

*************************************************
* definiëren van de geheugen map
*************************************************
incl "map512.asm" <op deze plaats wordt door de assembler tekst uit de file
                   map512.asm gelezen en mee geassembleerd

Wanneer er een editor open is waarin de in te lezen file ge-edit wordt, dan zal de assembler de tekst voor de in te lezen file uit deze editor lezen, en niet uit een eventuele gelijknamige file op disk.

Als de in te lezen file niet in een editor staat, wordt op de disk naar een file met de opgegeven naam gezocht.

Als de file niet gevonden kan worden, resulteert dit in een foutmelding. De assembler gaat desondanks verder met assembleren van de hoofd file.

De door de assembler in te lezen file kan zelf weer opnieuw verwijzen naar een in te lezen file. Dit is toegestaan tot 5 niveaus diep.

Wanneer de assembler een listing produceert, wordt daarin eveneens de listing van de ingelezen files opgenomen, alsof de tekst rechtstreeks in het programma was opgenomen in plaats van indirect via een verwijzing.

Listing aan- en uitzetten

Het is mogelijk de assembler van stukken van het programma geen listing te laten produceren. Dit is vooral handig wanneer u files 'include'. Van deze files weet u meestal wel wat erin staat, en het is dan niet nodig dat de assembler daar een uitgebreid rapport van maakt. Dat maakt de listing alleen maar langer.

U zet het genereren van een listing (tijdelijk) uit met de pseudo-instructie

NOLIST

Wanneer de assembler weer verder moet gaan met het produceren van de listing, gebruikt U de pseudo-instructie

LIST

Wanneer U bijvoorbeeld de tekst van een 'include' file niet in de listing opgenomen wilt hebben, kunt U het 'incl' stukje tussen 'nolist' en 'list' plaatsen:

nolist
incl 'map512.asm'
list

U kunt de 'nolist' en 'list' pseudo-instructies natuurlijk ook opnemen in de 'include' file zelf. In dat geval krijgt u van deze file nooit een listing, tenzij u de file verandert (de 'nolist' instructie verwijdert.)

Assembler onderbreken

De assembler kan onderbroken. Als de assembler op deze wijze gestopt wordt, komt er in de listing een melding: 'Interrupted'.

Door de assembler te onderbreken wordt er geen nieuwe code voor de micro-controller aangemaakt. De bestaande code die voor het betreffende programma mogelijk aanwezig was, gaat verloren.

Two-pass assembleren

Indien de assembler de tekst éénmaal zou lezen, dan zou u nooit een label kunnen gebruiken voordat het een waarde heeft gekregen. De waarde voor het label is dan immers nog niet aan de assembler bekend. Om dit te voorkomen leest de assembler de tekst twee keer, en vult de tweede keer in wat tijdens de eerste keer lezen nog niet bekend was. Dit noemt men 'two-pass' assembleren. Natuurlijk is het mogelijk om constructies te bedenken die ook met twee keer lezen nog niet oplosbaar zijn. In zo'n geval geeft de assembler een foutmelding, en moet U het programma wat aanpassen.


Volgende ]

© 2005...2008 Elomax [Voorwaarden ]