Montører MASM, TASM og WASM er forskjellige. Å lage enkle programmer for dem er imidlertid praktisk talt ikke forskjellig, bortsett fra monteringen og selve koblingen.
Så vårt første program for MASM, TASM og WASM, som viser den engelske bokstaven "A" ved gjeldende markørposisjon, det vil si i øvre venstre hjørne av skjermen:
Modell bittesmå .code ORG 100t start: MOV AH, 2 MOV DL, 41t INT 21t INT 20t END start Denne teksten kan skrives inn i et hvilket som helst enkelt tekstredigeringsprogram - for eksempel NotePad fra WINDOWS (men ikke i Word eller på annen måte "fantastisk") . Jeg anbefaler imidlertid et "avansert" tekstredigeringsprogram med syntaksutheving, for eksempel PSPad (se avsnitt). Deretter lagrer vi denne filen med filtypen .asm, for eksempel i MYPROG-mappen. La oss kalle filen atest. Så vi fikk: C: \ MYPROG \ atest.asm.
MERK
Merk at i den første kommandoen skrev vi 2 i stedet for 02h. MASM, TASM og WASM, som Emu8086, tar seg slike friheter. Selv om du kan skrive 02h - vil det ikke være noen feil.
Forklaringer til programmet:
.modell bittesmå- 1. linje. .model-direktivet definerer minnemodellen for en bestemt filtype. I vårt tilfelle er dette en fil med COM-utvidelsen, så vi velger den lille modellen, som kombinerer kode-, data- og stabelsegmentene. Den lille modellen er designet for å lage COM-filer.
.kode- 2. linje. Dette direktivet starter et kodesegment.
ORG 100h- 3. linje. Denne kommandoen setter verdien av programtelleren til 100h, fordi når COM-filen lastes inn i minnet, tildeler DOS de første 256 bytene for PSP-datablokken (desimaltall 256 er lik heksadesimal 100h). Programkoden er kun plassert etter denne blokken. Alle programmer som er kompilert til COM-filer må starte med dette direktivet.
start: MOV AH, 02h- 4. linje. Startetiketten plasseres foran den første kommandoen i programmet og vil bli brukt i END-direktivet for å indikere hvilken kommando programmet starter med. MOV-instruksjonen setter verdien av den andre operanden inn i den første operanden. Det vil si at verdien 02h plasseres i AH-registeret. Hvorfor gjøres dette? 02h er en DOS-funksjon som skriver ut et tegn på skjermen. Vi skriver et program for DOS, så vi bruker kommandoene til dette operativsystemet (OS). Og vi skriver denne funksjonen (eller rettere sagt nummeret) inn i AH-registeret, fordi interrupt 21h bruker dette spesielle registeret.
MOV DL, 41 timer- 5. linje. Tegnkoden "A" er lagret i DL-registeret. ASCII-tegnkoden for "A" er 41 timer.
INT 21t- 6. linje. Dette er selve avbruddet 21h - kommandoen som kaller opp DOS-systemfunksjonen spesifisert i AH-registeret (i vårt eksempel er dette 02h-funksjonen). INT 21h-kommandoen er hovedmetoden for interaksjon mellom programmer og OS.
INT 20h- 7. linje. Dette er et avbrudd som ber operativsystemet om å avslutte programmet og overføre kontrollen til konsollapplikasjonen. I tilfelle programmet allerede er kompilert og lansert fra OS, vil INT 20h-kommandoen returnere oss til OS (for eksempel til DOS).
SLUTT start- 8. linje. END-direktivet avslutter programmet mens det spesifiserer ved hvilken etikettkjøring skal starte.
Bestem enheten som den er kompilert forParametrene som sendes til direktivet er en sekvens av uttrykk atskilt med komma. Hvert uttrykk må enten være et tall i området (-128..255), eller i
resultatet av beregningen skal gi et resultat i samme område, ellers blir tallet avkortet til en byte, og UTEN å gi advarsler.
Hvis direktivet mottar mer enn én parameter og det gjeldende segmentet er programsegmentet, blir parameterne pakket inn i ord (den første parameteren er den minst signifikante byten), og hvis
antall parametere er oddetall, da vil det siste uttrykket avkortes til en byte og skrives som et ord med den mest signifikante byten lik null, selv om det er en til
DB direktiv.
Syntaks:
LABEL: .DB expression_list
Eksempel:
.CSEG
consts: .DB 0, 255, 0b01010101, -128, 0xaa
Parametrene som sendes til direktivet er en sekvens av uttrykk atskilt med komma. Hvert uttrykk må enten være et tall i området (-32768..65535), eller
som følge av utregningen skal det gi et resultat i samme område, ellers blir tallet avkortet til et ord, og UTEN å gi advarsler.
Syntaks:
LABEL: .DW expressionlist
Eksempel:
.CSEG
varlist: .DW 0, 0xffff, 0b1001110001010101, -32768, 65535
Syntaks:
.ENDMACRO
Eksempel:
.MACRO SUBI16; Begynn å definere en makro
subi r16, lav (@ 0); Trekk fra den minst signifikante byten av den første parameteren
sbci r17, høy (@ 0); Trekk fra den høye byten til den første parameteren
.ENDMACRO
EQU - Sett konstant uttrykk
EQU-direktivet tildeler etiketten en verdi. Denne etiketten kan senere brukes i uttrykk. Etiketten som er tildelt en verdi av dette direktivet kan ikke være det
er tilordnet på nytt og verdien kan ikke endres.
Syntaks:
.EQU label = uttrykk
Eksempel:
.EQU io_offset = 0x23
.EQU porta = io_offset + 2
CSEG; Begynnelsen av datasegmentet
clr r2; Tøm register r2
ut porta, r2; Skriv til Port A
ESEG - EEPROM-segment
ESEG-direktivet definerer begynnelsen av EEPROM-segmentet. En kildefil kan bestå av flere EEPROM-segmenter som kombineres til ett segment under kompilering.
EEPROM-segmentet består vanligvis bare av direktiver,
href = "# DW - Definer konstante ord i programminnet og EEPROM"> DW
byte posisjon tellere. Direktivet kan brukes til å plassere
variabler på ønsket plassering av EEPROM. Direktivet har ingen parametere.
Syntaks:
.ESEG
Eksempel:
var1: .BYTE 1; reserver 1 byte for var1
tabell: .BYTE tab_size; reserver tab_size bytes.
ESEG
eevar1: .DW 0xffff; initialisere 1 ord i EEPROM
EXIT - Avslutt fil
Når kompilatoren møter EXIT-direktivet, slutter kompilatoren å kompilere denne filen. Hvis direktivet brukes i en vedlagt fil (se direktivet
href = "# INKLUDERE - Inkluder en annen fil"> INKLUDERE
Hvis filen ikke er nestet, stopper kompileringen.
Syntaks:
.EXIT
Eksempel:
.EXIT; Avslutt denne filen
INKLUDERE - Legg ved en annen fil
Etter å ha møtt INCLUDE-direktivet, åpner kompilatoren filen som er spesifisert i den, kompilerer den til filen slutter eller direktivet påtreffes
href = "# AVSLUTT - Avslutt denne filen"> AVSLUTT
INKLUDERE. Den vedlagte filen kan også inneholde INCLUDE-direktiver.
Syntaks:
.INCLUDE "filnavn"
Eksempel:
; iodefs.asm fil:
.EQU sreg = 0x3f; Statusregister
.EQU sphigh = 0x3e; Høy byte av stabelpekeren
.EQU splow = 0x3d; Lav byte av stabelpekeren
; incdemo.asm-filen
.INKLUDERE iodefs.asm; Innebygd portdefinisjoner
i r0, sreg; Les statusregister
LIST – Aktiver oppføringsgenerering
LIST-direktivet ber kompilatoren lage en oppføring. Listing er en kombinasjon av monteringskode, adresser og opkoder. Av
Som standard er oppføringsgenerering aktivert, men dette direktivet brukes sammen med direktivet for å få lister over individuelle deler av kildefilene.
Syntaks:
.LISTE
Eksempel:
LISTMAC – Aktiver utvidende makroer i oppføringen
Etter LISMAC-direktivet vil kompilatoren vise innholdet i makroen i listen. Som standard viser oppføringen bare kallet til makroen og bestått
alternativer.
Syntaks:
.LISTMAC
Eksempel:
.MACRO MACX; Makrodefinisjon
legg til r0, @ 0; Makrokropp
eor r1, @ 1
LISTMAC; Aktiver utvidende makroer
MACX r2, r1; Kalle opp makroen (oppføringen vil vise brødteksten til makroen)
MAKRO - Makrostart
Definisjonen av en makro begynner med MACRO-direktivet. Navnet på makroen sendes til direktivet som en parameter. Når du møter navnet på makroen senere i teksten til programmet,
kompilatoren erstatter dette navnet med brødteksten til makroen. En makro kan ha opptil 10 parametere, som du får tilgang til i kroppen via @ [e-postbeskyttet] Når den kalles opp, vises parameterne
separert av kommaer. Definisjonen av en makro ender med et direktiv.
Som standard inkluderer oppføringen bare et kall til makroen; for å utvide makroen må du bruke direktivet. Makroen i listen vises med et +-tegn.
Syntaks:
.MAKRO makronavn
Eksempel:
.MACRO SUBI16; Makrodefinisjon start
subi @ 1, lav (@ 0); Trekk fra den lave byten til parameter 0 fra parameter 1
sbci @ 2, høy (@ 0); Trekk fra den høye byten til parameter 0 fra parameter 2
.ENDMACRO; Slutt på makrodefinisjon
CSEG; Start av programsegmentet
SUBI16 0x1234, r16, r17; Trekk fra 0x1234 fra r17: r16
NOLIST – Deaktiver oppføringsgenerering
NOLIST-direktivet ber kompilatoren slutte å generere oppføringen. Oppføring er en kombinasjon av monteringskode, adresser og
operasjonskoder. Som standard er oppføringsgenerering aktivert, men kan deaktiveres av dette direktivet. I tillegg kan dette direktivet brukes
sammen med et direktiv for innhenting av lister over enkeltdeler
kildefiler
Syntaks:
.NOLIST
Eksempel:
.NOLIST; Deaktiver oppføringsgenerering
.INCLUDE "macro.inc"; Vedlagte filer vil ikke være det
.INCLUDE "const.def"; vises i oppføringen
.LISTE; Aktiver oppføringsgenerering
ORG - Sett posisjon i segment
ORG-direktivet setter posisjonstelleren lik den gitte verdien, som sendes som en parameter. For datasegmentet setter den posisjonstelleren til
SRAM (RAM), for programsegmentet er dette programtelleren, og for EEPROM-segmentet er dette posisjonen i EEPROM. Hvis direktivet innledes med en etikett (på samme linje), da
etiketten er plassert på adressen angitt i direktivparameteren. Før kompilering starter, er programtelleren og EEPROM-telleren null, og RAM-telleren er 32
(siden adressene 0-31 er okkupert av registre). Vær oppmerksom på at byte-tellere brukes for RAM og EEPROM, og ord-for-ord-tellere for programsegmentet.
Syntaks:
.ORG uttrykk
Eksempel:
DSEG; Begynnelsen av datasegmentet
ORG 0x37; Sett SRAM-adressen til 0x37
variabel: .BYTE 1; Reserver en byte på adressen 0x37H
CSEG
.ORG 0x10; Sett programvaretelleren til 0x10
mov r0, r1; Denne kommandoen vil være plassert på 0x10
SET - Angi variabelens symbolske ekvivalent til et uttrykk
SET-direktivet tildeler en viss betydning til et navn. Dette navnet kan senere brukes i uttrykk. Dessuten, i motsetning til direktivet
href = "# EQU - Sett et symbol lik et uttrykk"> EQU
Syntaks:
.SET navn = uttrykk
Eksempel:
.SET io_offset = 0x23
.SET porta = io_offset + 2
CSEG; Kodesegmentstart
clr r2; Tøm register 2
Tagger
En etikett for monteringsspråk kan inneholde følgende tegn:
Bokstaver: A til Å og a til å
Tall: 0 til 9
Spesialtegn: spørsmålstegn (?)
punktum (.) (kun første tegn)
kommersiell gulvskilt (@)
understrek (_)
dollar ($)
Det første tegnet i etiketten må være en bokstav eller spesialtegn. Sifferet kan ikke være det første tegnet på etiketten, men tegnene $ og? noen ganger har spesielle betydninger og anbefales vanligvis ikke for bruk. Store og små bokstaver er de samme som standard, men forskjellen kan gjøres ved å spesifisere et alternativ på assembler-kommandolinjen. Maksimal etikettlengde er 31 tegn. Eksempler på etiketter: COUNT, PAGE25, $ E10. Det anbefales å bruke beskrivende og semantiske etiketter. Registernavn som AX, DI eller AL er reservert og brukes kun for å indikere tilsvarende registre.
Hvis etiketten er plassert før prosessorinstruksjonen, er symbolet ":" (kolon) alltid plassert umiddelbart etter den, som forteller assembleren å lage en variabel med dette navnet som inneholder adressen til den gjeldende instruksjonen:
some_loop:
loopne some_loop
Når en etikett plasseres foran et monteringsdirektiv, viser det seg vanligvis å være en av operandene til det direktivet, og kolon brukes ikke:
kodesegment
lodsw; lese et ord fra en streng,
cmp øks, 7; hvis det er 7 - gå ut av løkken
codesg slutter
Tenk på direktivene som fungerer direkte med etiketter og deres verdier: LABEL, EQU og =.
LABEL-direktivet
Etiketttypeetikett LABEL-direktivet definerer en etikett og definerer dens type. Typen kan være en av: BYTE (byte), WORD (ord), DWORD (dobbeltord), FWORD (6 byte), QWORD (firedobbelt ord), TBYTE (10 byte), NEAR (nærmerke), FAR (langt) merke) ). Etiketten mottar en verdi lik adressen til neste kommando eller neste data, og typen spesifisert eksplisitt. Avhengig av typen kommando
mov-etikett, 0 vil skrive til minnet en byte (ord, dobbeltord, etc.) fylt med nuller, og kommandoen
anropsetikett vil utføre en nær eller fjern subrutineanrop.
Ved hjelp av LABEL-direktivet er det praktisk å organisere tilgangen til de samme dataene, både bytes og ord, ved å definere to etiketter med ulike typer foran dataene.
EQU-direktivet
EQU-direktivet tildeler en verdi til etiketten, som bestemmes som et resultat av heltallsuttrykket på høyre side. Resultatet av dette uttrykket kan være et heltall, en adresse eller en hvilken som helst streng med tegn:
equ label uttrykk
sannhet equ 1
melding1 equ "Prøv igjen $"
var2 equ 4
cmp øks, sannhet; cmp øks, 1
db melding1; db "Prøv igjen $"
mov øks, var2; mov ax, 4 EQU-direktivet brukes oftest for å introdusere parametere som er felles for hele programmet, lik #define-kommandoen til C-forprosessoren.
Direktiv =
=-direktivet tilsvarer EQU, men etiketten den definerer kan bare ha heltallsverdier. I tillegg kan etiketten spesifisert i dette direktivet overstyres.
Hver assembler tilbyr et helt sett med spesielle forhåndsdefinerte etiketter - dette kan være gjeldende dato (@date eller ??dato), prosessortype (@cpu) eller navnet på et bestemt programsegment, men den eneste forhåndsdefinerte etiketten som støttes av alle assemblers. vi vurderer er $ ... Den samsvarer alltid med gjeldende adresse. For eksempel kommandoen
Jmp $
utfører et ubetinget hopp på seg selv, slik at en evig løkke skapes fra én instruksjon.
For bedre å forstå det hele, skrev jeg et lite program. Den samme "Hello World", men på en ny måte :) Teksten er under:
Programmet er satt sammen av TASM og MASM, men EXE-filen satt sammen av MASM er én byte større. Merk at kommandoen mov dx, offset msg er erstattet med kommandoen lea dx, msgb. LEA legger offsetadressen til de spesifiserte dataene i DX, dvs. gjør det samme som mov-kommandoen med offset. Jeg anbefaler å se på dette under feilsøkeren.
Vi ser nøye på monteringslistene og finner forskjellen.
Interessant nok samlet TASM LEA-instruksjonen i dette tilfellet som en MOV-instruksjon (operasjonskode BA), og MASM satt sammen LEA-instruksjonen til en annen opkode - 8D16, som økte programstørrelsen med 1 byte. Jeg vet ikke hvorfor han bestemte seg for å gjøre dette ennå, men det ville vært interessant å finne ut.
Direktiver er kompilatorkontrollkommandoer. Erklæringen til hver av dem må begynne med et punktum. Praksis viser at i enhver montør er det bare rundt 10 ... 20 direktiver som brukes mest intensivt. Alle andre er enten valgfrie eller er ansvarlige for å administrere kun mindre egenskaper til kompilatoren. De "hoved"-direktivene, typiske for montører av andre prosessorer, inkluderer direktivene.equ, .org, .def, .сseg, .dseg, etc. Vel, direktiver som dq, .exit, .listmac er egentlig veldig sjeldne i ekte programmer. Nedenfor er en liste, beskrivelse og eksempler på bruk av direktivene til den proprietære assembleren av AVR-mikrokontrollere.
.include-direktivet erstatter en tekstfil i stedet for programmet der den brukes. I tillegg til dette kan selve erstatningsfilen også inneholde et .include-direktiv. Hvis filen er plassert i prosjektkatalogen eller i en av tjenestemappene, er det bare tillatt å spesifisere en kobling til navnet i stedet for den fullstendige banen.
.Inkluder direktiv
Skrive syntaks:
.include "(bane til fil)"
Brukseksempel:
Inkluder "m8def.inc"; sett inn standard overskriftsfil
.exit-direktivet forteller assembleren hvor kildefilen slutter. Alle operatører etter direktivet blir usynlige for kompilatoren. Hvis .exit forekommer i en include-fil, slutter prosjektsammenstillingen med linjen der .include-direktivet er plassert. I fravær av .exit-direktivet regnes den siste linjen i kildeteksten som byggeendepunktet.
.Exit-direktiv
Skrive syntaks:
.exit
Brukseksempel:
Avslutt; slutten av filen
.nolist- og .list-direktivene styrer listefilen, som vanligvis genereres etter at prosjektet er bygget. Den første av dem forbyr, og den andre tillater følgelig utdata av informasjon til en fil. .list-direktivet overstyrer effekten av .nolist og omvendt.
.Nolist, .list direktiver
Skrive syntaks:
.nolist, .list
Brukseksempel:
Nolist; forby utmating av teksten til filen "m8def.inc". Inkluder "m8def.inc"; til programoppføringen file.list; fortsett å skrive ut informasjon
The.equ-direktivet tildeler en numerisk verdi til et symbolsk navn. Det symbolske navnet må være unikt og kan ikke endres mens programmet skrives. Direktivet kan ikke brukes til å tildele symbolske navn til generelle registre.
Equ-direktivet
Skrive syntaks:
.equ (symbolsk navn) = (uttrykk)
Brukseksempel:
Equ DDRB = 0x17; tilordne DDRB-navn til 0x17 .equ PORTB = DDRB + 1; tilordne PORTB-navn til 0x18
.set-direktivet gjør det samme som .equ-direktivet. Men i motsetning til sistnevnte kan det symbolske navnet omdefineres hvor som helst i programmet.
.Sett direktiv
Skrive syntaks:
.set (symbolsk navn) = (uttrykk)
Brukseksempel:
Sett OFFSET = 0x100; tildeler OFFSET-navnet til 0x100. .sett OFFSET = OFFSET + 1; overstyr OFFSET-verdien
.def-direktivet tildeler et symbolsk navn til et av de generelle registrene. I programmets videre løp kan dette navnet overstyres av .undef-direktivet.
.Def, .undef direktiver
Skrive syntaks:
.def (symbolsk navn) = (casebok)
.undef (symbolsk navn)
Brukseksempel:
Def temp = R16; tilordne navnet temp for å registrere R16 .undef temp; avbryt videre bruk av navnet temp
Direktivene db, .dw, .dd, .dq er utformet for å reservere mikrokontrollerminnet for initialiserte data. Alle kan bare brukes i kode- og EEPROM-segmenter. Forskjellen mellom disse direktivene ligger i bitbredden til de representerte dataene. db-direktivet reserverer bytes, .dw - ord, .dd - doble ord. I sjeldne tilfeller kan det også være praktisk å bruke .dq-direktivet for å sikkerhetskopiere 64-biters data.
Db, .dw, .dd, .dq-direktiver
Skrive syntaks:
(etikett): .db (8-biters data)
(etikett): .dw (16-biters data)
(etikett): .dd (32-biters data)
(etikett): .dq (64-biters data)
Brukseksempel:
Etikett: .db 0xFA, 250, -6, 0b11111010 .dw 0xFADE, 64222, -1314, 0b1111101011011110 .dd 0xFADEEFCA, 42089184378, 7089184378, 7089184378, 8089184378, 7089184378, 7089184378, 7089184378, 7089184378, 7089184378, 7089184378, 7089184372
.byte-direktivet reserverer minne for uinitialiserte data i SRAM- og EEPROM-segmentene.
.Byte-direktivet
Skrive syntaks:
(etikett): .byte (mengde data som skal sikkerhetskopieres)
Brukseksempel:
Equ PAGESIZE = 0x20 buffer:. byte 2 * PAGESIZE; reserver 64 byte i SRAM
Dseg, .eseg, .cseg-direktivene definerer begynnelsen av henholdsvis data, EEPROM og kodesegmenter. I kildefilen kan hvert av segmentene bare representeres i én instans. Hvis alle disse direktivene er fraværende i programmet, antar kompilatoren som standard at alle operatører er plassert i kodedelen.
Dseg, .eseg, .cseg-direktiver
Skrive syntaks:
.dseg
.eseg
.cseg
Brukseksempel:
Dseg; start av datasegmentbuffer:. byte 32, reserve 32 byte for buffer i SRAM .cseg, start av kodesegment rjmp initial. streng: .db "ATmega8", 0; streng lagret i FLASH-minne .eseg; begynnelsen av EEPROM-minnesegmentet _var: .byte 2; reserver 2 byte for variabelen _var _cnst: .db 0xAA; reserver en byte for variabelen _cnst = 0xAA
.Org-direktivet lar kompilatoren sette en startadresse innenfor kode-, data- og EEPROM-segmenter. Når det brukes i et kodesegment, spesifiserer direktivet adressen til 16-biters programord.
Direktiv.org
Skrive syntaks:
.org (startadresse)
Brukseksempel:
Equ SRAM_START = 0x60 .equ RAMEND = 0x045F .dseg; start av data segment.org SRAM_START; reserver 32 byte i SRAM for buffer, buffer:. byte 32; starter på adresse 0x60 .cseg; start på kode segment.org 0; tilbakestill vektor på adresse 0 rjmp initial. .org 0x50; start av hovedprogrammet fra adresse 0x50 initial: ldi temp, high (RAMEND); initialisering av stack out SPH, temp ldi temp, low (RAMEND) out SPL, temp.
Direktivs.macro, .endmacro (.endm), som definerer henholdsvis begynnelsen og slutten av makroen.
Direktivs.macro, .endmacro (.endm)
Skrive syntaks:
.macro (makronavn)
Brukseksempel:
Makro set_bit; deklarer makroen for å sette portbiten sbi @ 0, @ 1; sett bit @ 1 av portregisteret @ 0 sbi @ 0-1, @ 1; sett linje @ 1 i DDRx-registeret .endm til utgang. set_bit PORTB, 0; satt på linje 0 i port B logikk 1
.listmac-direktivet muliggjør utvidet utdata av teksten til makroer i listefilen. I dette tilfellet vises hele innholdet i hver makrodefinisjon som påtreffes i programmet. Hvis direktivet ikke brukes, vises ikke koden inne i makroen.
.Listmac-direktivet
Skrive syntaks:
.listmac
Brukseksempel:
Listmac; tillat utvidelse av makrotekst i listefil
.message, .warning, .error-direktivene er utformet for å vise tilleggsinformasjon om programkompileringsfremdriften i prosjektmonteringsvinduet. .message-direktivet genererer en melding for linjen der anropet ble oppdaget. Bruk av .warning resulterer i en advarsel og .error resulterer i en feilmelding. I sistnevnte tilfelle stopper monteringen av prosjektet.
.Melding, .advarsel, .feildirektiver
Skrive syntaks:
.message "(tekstmelding)"
.warning "(advarselstekst)"
.error "(feilmeldingstekst)"
Brukseksempel:
Melding "Makroer har blitt kalt her." .advarsel "For høy frekvens!" .error "Feil makroargument!"
En gruppe betingede kompileringsdirektiver .ifdef, .ifndef, .if, .else, elif, .endif brukes til å sette inn programkode avhengig av ulike forhold. .ifdef-direktivet ser etter deklarasjonen av et symbolsk navn. Direktivet kan følges av et sett med kommandoer som vil bli erstattet i teksten hvis testbetingelsen er "sann" (navnet er deklarert). .ifndef-direktivet er det motsatte. Ifdef sjekker for fravær av en symbolsk navneerklæring. .if-direktivet utfører kodesubstitusjon når sammenligningsbetingelsen spesifisert som parameteren er oppfylt. Kommandoene som må utføres hvis betingelsen for .if-direktivet er "false" - er plassert etter .else-direktivet. Forgrening av typen "hvis" - "da" kan ha flere hekkenivåer takket være .elif-direktivet. Hver kontrollblokk som starter med .ifdef, .ifndef, .if må lukkes med.endif-direktivet.
If, .ifdef, .ifndef, .else, elif, .endif-direktiver
Skrive syntaks:
.ifdef (karakter) (eller .ifndef (karakter))
.if (tilstand)
.else (uttrykk) (eller .elif (tilstand))
.slutt om
Brukseksempel:
Makro del_ms; makro som danner tidsforsinkelsen i ms ifndef FREQ; hvis FREQ-konstanten (frekvens i Hz) ikke er deklarert, .advarsel "Udefinert FREQ-konstan!" ; gi en advarsel og ec FREQ = 1000000; sett standarden til 1 MHz; endif .equ DELAY = (@ 0 * FREQ) / 4000; verdi for å stille inn tidsforsinkelsen hvis DELAY> 65535; hvis DELAY er større enn 2 byte, deretter feilen "Heltall overflyt i DELAY!" ; implementering av makroen er ikke mulig .else trykk XL; lagre arbeidsregistrene XL, XH trykk XH ldi XH, høy (DELAY); tidsforsinkelsessyklus ldi XL, lav (DELAY) sbiw XH: XL, 1 brne PC-1 pop XH pop XL, gjenopprett arbeidsregistrene XH, XL fra stabelen .endif .endm. .equ FREQ = 2 000 000; 2 MHz klokkeerklæring. del_ms 25; danner en tidsforsinkelse på 25 ms
Ved skriving av programmer i Assembly-språk brukes direktiver som angir for kompilatoren posisjonen til programmet i minnet, definerer makroer, initialiserer minne osv. Listen over direktiver og deres beskrivelse er gitt i tabell. 1.8. Alle direktiver starter med en prikk. La oss kort liste opp funksjonene som utføres av direktiver i hvert av segmentene.
Programsegmentet åpnes med .CSEG-direktivet. Hvis programmet starter med dette segmentet, kan direktivet mangle. I et programsegment, ved å bruke .ORG-direktivet, kan du spesifisere begynnelsen av segmentet.
DB-direktivet for et segment definerer en enkelt byte, eller gruppe av byte, av konstanter skrevet til Flash-minnet. DW-direktivet definerer et ord eller en gruppe ord som skal lagres i minnet som konstanter. Starten av skrivekonstanter bestemmes av etiketten foran det tilsvarende direktivet. De oppregnede konstantene er atskilt med komma.
.DEF-direktivet tildeler et symbolsk navn til registeret. .EQU, .SET-direktivene tildeler en verdi til navnet. Navnet som er tildelt en verdi av .EQU-direktivet kan ikke tilordnes på nytt og verdien kan ikke endres. Navnet som er tildelt av .ET-direktivet kan endres av et annet .ET-direktiv.
DEVICE-direktivet definerer typen målmikrokontroller som skal brukes til å kjøre programmet. Tilstedeværelsen av dette direktivet kobler sammen midlene for å kontrollere programinstruksjonene i forhold til den fysiske enheten, advarsel om umuligheten av å utføre noen instruksjoner, størrelsen på minnet som brukes, etc.
.INCLUDE-direktivet med filnavnet brukes til å inkludere en annen fil i programteksten.
Tabell 1.8. Liste over direktiver
direktiv |
Beskrivelse |
Reserver byte i RAM |
Programsegment |
Definer en byte - en konstant i Flash-minnet, eller |
Tilordne et symbolsk navn til et register |
Spesifiserer enheten som skal kompileres for |
program |
Datasegment |
Definerer et ord i Flash-minne eller EEPROM |
Slutt på makroen |
Sett konstant uttrykk |
EEPROM-segment |
Avslutter filen |
Legg ved en annen fil |
Aktiver oppføringsgenerering |
Aktiver utvidende makroer i oppføringen |
Makrostart |
Deaktiver oppføringsgenerering |
Still inn posisjon i segment |
Sett variabel til ekvivalent uttrykk |
.MACRO- og .ENDMACRO-direktivene rammer inn makrodefinisjonen. En makrodefinisjon kan ha opptil 10 parametere med faste navn @ 0,..., @ 9. Når du kaller en makro, spesifiseres parameterne som en liste i rekkefølgen av nummerering.
Datasegmentet begynner med .DSEG-direktivet. ORG- og BYTE-direktivene kan brukes i segmentet. BYTE-direktivet definerer antall byte som vil få tilgang til under programkjøring. Det reserverte området begynner på adressen angitt av etiketten før direktivet.
Et EEPROM-segment begynner med .ESEG-direktivet. .ORG, .DB, .DW-direktivene kan brukes i segmentet. DB-direktivet på et segment definerer en eller en gruppe byte som skal skrives til EEPROM. DW-direktivet definerer et ord eller en gruppe ord som skal skrives til EEPROM i par på 2 byte. Starten på å skrive bytes og ord bestemmes av etiketten foran det tilsvarende direktivet.
.LIST, .NOLIST, .LISTMAC-direktivene brukes til å kontrollere listeutdata.