Programmering i maskinkoder og i monteringsspråk. AVR-monteringsdirektiver

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 for

Parametrene 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

og etiketter. EEPROM-segmenter har sine egne

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

), så fortsetter kompileringen fra linjen etter INCLUDE-direktivet.

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

, så fortsetter den å kompilere den første filen fra linjen etter direktivet

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

navneverdien kan endres av et annet SET-direktiv.

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.