Programare în coduri mașină și limbaj de asamblare

Unul dintre cele mai importante elemente ale acestei părți a cărții sunt exemple de programe în codurile mașiniiși în limbajul ASAMBLARE. În imprimările acestor programe va trebui să folosim acest lucru

numite DIRECTIVE DE MONTAJ și acum, probabil, cel mai mult oră convenabilă pentru a face o idee despre ce este.

Ne vom uita la următoarele directive: ORG, EQU, DEFB, DEFW, DEFM și END, dar înainte de a începe să le luăm în considerare, trebuie să înțelegem ferm:

1. Directivele ASAMBLARE nu sunt comenzi ale procesorului Z8 0 și în acest sens nu au nicio legătură cu codul mașinii Z8 0.

2. ASSEMBLER este un program care traduce (traduce) textul scris de tine sub formă de mnemonici în cod obiect, care este codul mașinii. Și aceste directive ASSEMBLY sunt niște comenzi pentru programul de asamblare. Ele nu sunt traduse și nu vor fi incluse în codul obiect, dar vă vor face mai ușor să scrieți și, cel mai important, să citiți programul scris în mnemotec.

3. Există foarte multe programe de ASAMBLARE și fiecare dintre ele poate avea propriile sale directive. Ei pot avea aceleași directive, dar prezente cerințe diferite la utilizarea lor. Într-un cuvânt, trebuie să stabiliți metode specifice de utilizare a directivelor ASSEMBLY conform instrucțiunilor pentru programul de asamblare pe care îl utilizați (de exemplu, EDITAS, GENS 3, GENS 4, ZEUS etc.). Și, deși nu există standarde, totuși, unele concepte fundamentale pot fi încă identificate și ne vom concentra asupra lor.

3.1. Comentarii.

Vom începe cu cel mai simplu lucru - comentarii. Sunt scrise după simbolul „;”. (punct virgulă).

Desigur, înțelegeți că tot ceea ce este comentarii nu este compilat în codul mașinii de către ASSEMBLY - acest lucru nu este de niciun folos. Acestea servesc doar pentru a vă face mai convenabil să vă ocupați de o listă pe care altcineva sau dvs. ați compilat-o, dar cu mult timp în urmă.

De exemplu:

10 60001 LD E,A 2 0

După cum puteți vedea, linia poate

; Încărcat în registrul E care conține -; presa de baterie. ; A scăzut cu unu.

doar din comentariu.

Etichete.

Etichetele simplifică foarte mult scrierea programelor în mnemonicii ASSEMBLY. În operațiunile de salt JP, JR, DJNZ și subrutinele de apelare CALL, nu puteți specifica adresa la care doriți să săriți, ci înlocuiți o etichetă. Pe de altă parte, când scrieți comenzi pentru această adresă, puneți un semn și acolo, De exemplu:

10 60001 ÎNCEPE LD B,0 4

20 60003 AGAIN INC HL

40 60005 DJNZ, DIN NOU

3.2.

250 260 270

60110 60111 60113

LD A,(HL) CP 80H JR NZ,ÎNCEPE

După cum puteți vedea, este foarte convenabil. Puteți vedea imediat că de la linia 40 întoarcerea este la eticheta AGAIN dacă registrul B nu ajunge la zero. De la linia 270, revenirea este la eticheta BEGIN.

Cu siguranță are sens să alegeți un nume pentru etichetă care să se potrivească cu semnificația operației efectuate - acest lucru face lista de programe mai ușor de citit și de înțeles.

În timpul compilării, programul de asamblare în sine va calcula valorile decalajelor necesare în instrucțiunile procesorului și le va înlocui în loc de etichete. Deci, de exemplu, în linia 40 în loc de DJNZ din nou codul obiect va conține DJNZ FCH, care este același lucru.

În exemplul anterior, am folosit etichete foarte puțin. Cert este că atât referirea la etichetă, cât și eticheta în sine au fost în aceeași procedură. Dar ce se întâmplă dacă doriți să accesați o etichetă care se află într-o altă procedură pe care ați scris-o și ați compilat-o ieri și dacă trebuie să faceți tranziția la o procedură ROM și doriți să utilizați eticheta? În acest caz, directiva EQU vă va ajuta. Acesta atribuie o valoare numerică etichetei. Desigur, în timpul compilării această directivă nu este convertită în cod mașină în niciun fel, dar dacă există referințe la această etichetă în textul programului, atunci valoarea preluată din directiva EQU va fi înlocuită.

De exemplu, în programul dvs. trebuie să apelați în mod repetat procedurile ROM, să spuneți CLEAR (1EACH=7 8 52) și OUT-LINE (1856H=6230). Apoi, la începutul programului, specificați

de exemplu numindu-le CLEAR

directivă

valorile la mărcile lor, n

și OUT L.

CLAR

EQU 7 8 52

OUT L

EQU 62 3 0

ETICHETA

EQU 60016

apel

le stii pe astea

proceduri sau

prin marcaj.

60001

LD HL, (Etichetă)

60004

LD BC, 0008

60007

LD DE, (04 52)

60010

Apelați CLEAR

60013

Sunați-l pe L

60016

Pe loc

iti datorez

a avertiza,

exemple

din punct de vedere

software

exemple despre cum sunt folosite anumite directive ASSEMBLY și dacă aveți nevoie de un sens real în exemple, atunci îl veți obține puțin mai târziu, în capitolele următoare, unde vom analiza tehnici practice de programare.

Să aruncăm o altă privire la exemplul anterior. În rândul 30, trimitem perechii de registre HL ceea ce este conținut în adresa indicată de eticheta LABEL, care, conform directivei EQU, indică adresa 60016.

Deci, celulele 60016 și 60017 conțin unele date care pot fi utilizate ulterior de program. Puteți trimite singur aceste date către celule înainte de compilare. Și nu trebuie să utilizați codul de mașină pentru asta. Valorile inițialeîn celulele de memorie puteți seta folosind directivele DEFB, DEFW și DEFM.

DEFB - DEFINE BYTE - setează un octet.

DEFW - DEFINE WORD - setați un „cuvânt” (un „cuvânt” este doi octeți consecutivi. De obicei, aceasta este o adresă.) DEFM - DEFINE MESSAGE - setați un mesaj (aceștia sunt mai mulți octeți consecutivi). De obicei, programele de asamblare impun o limită a câți octeți pot fi specificați de o directivă DEFM, să spunem nu mai mult de cinci. Dar asta nu ar trebui să te îngrijoreze. Daca vrei sa intrebi mesaj lung, atunci puteți pune câte linii DEFM la rând doriți.

Deci, DEFB specifică un singur octet (0...255), DEFW specifică doi octeți consecutivi (0...65535), iar DEFM specifică un grup de octeți consecutivi - mesaj text, tabel de numere etc.

În exemplul nostru anterior, dacă dorim să stocăm un număr de doi octeți la adresele 60016 și 60017, linia 80 ar trebui scrisă astfel:

80 60016 DEFW 5C92H

90 60018

Să presupunem că doriți să stocați cuvântul „Spectrum” începând cu adresa 60135.

Cod pentru litera "S" Cod pentru litera "p" "e" "c" "t" "r"

"u" "m"

60135

60136

60137

60138

60139

60140

60141

60142

53H 7 0H 65H 63H 7 4H 72H 75H 6DH

DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB

îl puteți specifica în perechi de octeți:

Dar este mai ușor și mai corect să îl setați ca mesaj:

60135 DEFM 5370656374 ; "Spect"

60140 DEFM 72756D ; "rom"

Există un caz special la programarea în ASAMBLARE când textul programului trebuie introdus și prin DEFB sau DEFM. Acesta este cazul când scrieți un program pentru un calculator încorporat. La urma urmei, un program de asamblare poate traduce mnemonicii ASSEMBLY în codul mașinii, dar nu știe nimic despre codurile calculatorului și nu-și cunoaște mnemonicii. Codul calculatorului este o chestiune internă „Sinclair”, interpretarea sa

Programele aflate în ROM sunt procesate, iar codul calculatorului nu are nicio legătură cu procesorul și comenzile acestuia. Prin urmare, veți putea introduce comenzi ale calculatorului în programul de asamblare numai ca o secvență de octeți independenți, adică prin DEFB sau DEFM.

În prima parte a cărții, am folosit notații mnemonice pentru comenzile calculatorului, cum ar fi add, stk_data s_lt etc., și le-am scris cu o literă mică, spre deosebire de comenzile procesorului. Dar am făcut acest lucru înainte și vom continua să facem acest lucru doar de dragul înțelegerii și ușurinței înregistrării. Programul ASSEMBLY nu cunoaște astfel de mnemonici, ele nu sunt în dicționarul său.

Deci, cu ajutorul DEFB, DEFW și DEFM, ei setează valorile inițiale ale variabilelor programului, introduc tabele, mesaje și orice alte secvențe de date în program, chiar și

grafice, precum și secvențe de cod pe care programul de asamblare nu le înțelege ca comenzi ASSEMBLY.

3.5. Directive ORG, END.

Trebuie doar să luăm în considerare cele două directive cele mai banale. Directiva ORG declară adresa de la care va fi asamblat programul. Trebuie să fie prima directivă din codul sursă, deși în principiu pot exista comentarii înaintea acesteia.

Ai observat că în exemplele de mai sus am scris o coloană de adrese în stânga în care vor fi plasate anumite comenzi. Deci, acest lucru nu este necesar să faceți atunci când programați în ASSEMBLY. Este suficient să dai o directivă de la bun început

10 ORG 63000

iar apoi programul de asamblare însuși va calcula în ce celulă de memorie va fi amplasată această sau acea instrucțiune. Acest lucru simplifică foarte mult procesul de programare. Și dacă faci modificări la text gata, ASSEMBLATORUL însuși va corecta toate adresele.

Directiva END marchează sfârșitul unui program. Dacă mai este ceva după el, ASSEMBLEA îl va ignora în timpul compilării.

Acesta este, probabil, tot ceea ce merită să știți despre directivele ASSEMBLEEI pentru început. Acestea nu sunt toate directivele care pot fi întâlnite în viață, iar regulile de utilizare a acestora sunt diferite pentru diferiți asamblatori, dar în funcție de în general acest minim va satisface 90% din nevoile dvs. de informații, iar restul ar trebui să le obțineți din instrucțiunile pentru asamblatorul cu care lucrați.

Determinați dispozitivul pentru care este compilat

Parametrii trecuți directivei sunt o secvență de expresii separate prin virgule. Fiecare expresie trebuie să fie fie un număr din intervalul (-128..255), fie

rezultatul calculului trebuie să dea un rezultat în același interval, în caz contrar numărul se trunchiază la un octet, și FĂRĂ să emită avertismente.

Dacă o directivă primește mai mult de un parametru și segmentul de program curent este, atunci parametrii sunt împachetati în cuvinte (primul parametru este octetul mic) și dacă

numărul de parametri este impar, apoi ultima expresie va fi trunchiată la un octet și scrisă ca un cuvânt cu octetul cel mai semnificativ egal cu zero, chiar dacă urmează altul

Directiva DB.

Sintaxă:
LABEL: .DB expression_list

Exemplu:
.CSEG
const: .DB 0, 255, 0b01010101, -128, 0xaa

Parametrii trecuți directivei sunt o secvență de expresii separate prin virgule. Fiecare expresie trebuie să fie fie un număr din intervalul (-32768..65535), fie

ca urmare a calculului, acesta trebuie sa dea un rezultat in acelasi interval, in caz contrar numarul este trunchiat la un cuvant, si FARA a da avertismente.

Sintaxă:
LABEL: .DW expressionlist

Exemplu:
.CSEG
varlist: .DW 0, 0xffff, 0b1001110001010101, -32768, 65535

Sintaxă:
.ENDMACRO

Exemplu:
.MACRO SUBI16 ; Începerea unei definiții macro
subi r16,low(@0) ; Scădeți octetul mic al primului parametru
sbci r17,high(@0) ; Scădeți octetul înalt al primului parametru
.ENDMACRO

EQU – Setează expresia constantă

Directiva EQU atribuie o valoare unei etichete. Această etichetă poate fi folosită ulterior în expresii. O etichetă a cărei valoare este atribuită de această directivă nu poate fi

este reatribuit și valoarea sa nu poate fi modificată.

Sintaxă:
.EQU label = expresie

Exemplu:
.EQU io_offset = 0x23
.EQU porta = io_offset + 2

CSEG; Începutul segmentului de date
clr r2 ; Ștergeți registrul r2
out porta,r2 ; Scrieți în portul A

ESEG – segment EEPROM

Directiva ESEG definește începutul segmentului EEPROM. Fișierul sursă poate consta din mai multe segmente EEPROM, care sunt combinate într-un singur segment în timpul compilării.

Un segment EEPROM constă de obicei numai din directive,

href="#DW - Definiți cuvânt(e) constant(e) în memoria programului și EEPROM">DW

și semne. Segmentele EEPROM au propriile lor

contoare de poziție de octeți. Directiva poate fi folosită pentru a plasa

variabile în locul necesar în EEPROM. Directiva nu are parametri.

Sintaxă:
.ESEG

Exemplu:
var1: .BYTE 1 ; rezerva 1 octet pentru var1
tabel: .BYTE tab_size ; rezerva tab_size octeți.

ESEG
eevar1: .DW 0xffff ; inițializați 1 cuvânt în EEPROM

EXIT – Ieșiți din fișier

Când compilatorul întâlnește o directivă EXIT, se oprește compilarea. acest fișier. Dacă directiva este utilizată într-un fișier atașat (vezi directiva

href="#INCLUDE - Include alt fișier">INCLUDE

), apoi compilarea continuă de la linia care urmează directivei INCLUDE.

Dacă fișierul nu este imbricat, atunci compilarea se oprește.

Sintaxă:
.IEȘIRE

Exemplu:
.IEȘIRE ; Ieșiți din acest fișier

INCLUDE – Atașați un alt fișier

După ce a întâlnit o directivă INCLUDE, compilatorul deschide fișierul specificat în ea, îl compilează până când fișierul se termină sau este întâlnită directiva

href="#EXIT - Ieșiți din acest fișier">EXIT

, apoi continuă compilarea fișierului inițial din linia care urmează directivei

INCLUDE. Fișierul atașat poate conține și directive INCLUDE.

Sintaxă:
.INCLUDE „nume fișier”

Exemplu:
; fișier iodefs.asm:
.EQU sreg = 0x3f ; Registrul de stare
.EQU sphigh = 0x3e ; Indicator de stivă octet înalt
.EQU flux = 0x3d ; Octet scăzut al indicatorului stivei

; fișierul incdemo.asm
.INCLUSE iodefs.asm ; Definițiile portului de cuib
în r0,sreg ; Citiți registrul de stare

LIST – Activați generarea listelor

Directiva LIST îi spune compilatorului să creeze o listă. Lista este o combinație de cod de asamblare, adrese și coduri operaționale. De

În mod implicit, generarea de liste este activată, dar această directivă este utilizată împreună cu directiva pentru a obține liste de părți individuale fișiere sursă.

Sintaxă:
.LISTĂ

Exemplu:

LISTMAC – Activați extinderea macrocomenzii în listare

După directiva LISTMAC, compilatorul va afișa conținutul macrocomenzii în listă. În mod implicit, lista arată doar apelul macro și cel transmis

Opțiuni.

Sintaxă:
.LISTMAC

Exemplu:
.MACRO MACX ; Definiție macro
adăugați r0,@0 ; Corpul macro
eor r1,@1

LISTMAC; Activați extinderea macrocomenzii
MACX r2,r1; Apelarea unei macrocomenzi (corpul macrocomenzii va fi afișat în listă)

MACRO – Începutul unei macrocomenzi

Definiția unei macrocomenzi începe cu directiva MACRO. Numele macro-ului este transmis directivei ca parametru. Dacă întâlniți un nume de macrocomandă mai târziu în textul programului,

compilatorul înlocuiește acest nume cu corpul macrocomenzii. O macrocomandă poate avea până la 10 parametri, care sunt accesați prin @0-@9 în corpul său. Când sunt apelați, parametrii sunt listați

separate prin virgule. Definiția macro se termină cu o directivă.

În mod implicit, numai apelul macro este inclus în listare pentru a extinde macro, trebuie să utilizați directiva; Macrocomanda din listă este afișată cu semnul +.

Sintaxă:
.MACRO nume de macrocomandă

Exemplu:
.MACRO SUBI16 ; Începutul definiției macro
subi @1,low(@0) ; Scădeți octetul mic al parametrului 0 din parametrul 1
sbci @2,high(@0) ; Scădeți octetul mare al parametrului 0 din parametrul 2
.ENDMACRO ; Sfârșitul definiției macro

CSEG; Începutul segmentului de program
SUBI16 0x1234,r16,r17 ; Scădeți 0x1234 din r17:r16

NOLIST – Dezactivează generarea listelor

Directiva NOLIST îi spune compilatorului să nu mai genereze liste. Lista este o combinație de cod de asamblare, adrese și

coduri de operare. În mod implicit, generarea listelor este activată, dar poate fi dezactivată de această directivă. În plus, această directivă poate fi utilizată

împreună cu o directivă pentru a obține liste de piese individuale

fișiere sursă

Sintaxă:
.NOLIST

Exemplu:
.NOLIST ; Dezactivați generarea înregistrării
.INCLUSE "macro.inc" ; Fișierele atașate nu vor fi
.INCLUSE "const.def" ; afișat în listare
.LISTA ; Activați generarea înregistrării

ORG – Setați poziția în segment

Directiva ORG setează contorul de poziție la o valoare dată, care este transmisă ca parametru. Pentru segmentul de date, setează contorul de poziție la

SRAM (RAM), pentru un segment de program acesta este contorul de program, iar pentru un segment EEPROM aceasta este poziția în EEPROM. Dacă directiva este precedată de o etichetă (pe aceeași linie), atunci

eticheta este plasată la adresa specificată în parametrul directivei. Înainte de a începe compilarea, contorul de program și contorul EEPROM sunt egale cu zero, iar contorul RAM este egal cu 32

(deoarece adresele 0-31 sunt ocupate de registre). Vă rugăm să rețineți că contoarele de octeți sunt folosite pentru RAM și EEPROM, iar contoarele cuvânt cu cuvânt sunt folosite pentru segmentul de program.

Sintaxă:
.ORG expresie

Exemplu:
.DSEG; Începutul segmentului de date

ORG 0x37 ; Setați adresa SRAM la 0x37
variabilă: .BYTE 1 ; Rezervați un octet la adresa 0x37H

CSEG
.ORG 0x10 ; Setați contorul de programe la 0x10
mov r0,r1 ; Această comandă va fi localizat la adresa 0x10

SET – Setează echivalentul simbolic variabil al unei expresii

Directiva SET atribuie un sens unui nume. Acest nume poate fi folosit ulterior în expresii. În plus, spre deosebire de directivă

href="#EQU - Setați un simbol egal cu o expresie">EQU

valoarea numelui poate fi modificată printr-o altă directivă SET.

Sintaxă:
.SET nume = expresie

Exemplu:
.SET io_offset = 0x23
.SET porta = io_offset + 2

CSEG; Începutul segmentului de cod
clr r2 ; Ștergeți registrul 2

Asamblatorii MASM, TASM și WASM diferă unul de celălalt. Cu toate acestea, crearea de programe simple pentru ei practic nu are diferențe, cu excepția ansamblului și a legăturii în sine.

Deci primul nostru program pentru MASM, TASM și WASM care iese scrisoare engleză„A” la poziția curentă a cursorului, adică în colțul din stânga sus al ecranului:

Model minuscul .code ORG 100h start: MOV AH,2 MOV DL,41h INT 21h INT 20h END start Acest text poate fi tastat în orice limbaj simplu editor de text- de exemplu, în NotePad din WINDOWS (dar nu în Word sau alte „sofisticate”). Cu toate acestea, recomand un editor de text „avansat” cu evidențiere de sintaxă, precum PSPad (vezi secțiunea). Apoi salvăm acest fișier cu extensia .asm, de exemplu, în folderul MYPROG. Să numim dosarul atest. Deci, am primit: C:\MYPROG\atest.asm.

NOTĂ
Vă rugăm să rețineți că în prima comandă am scris 2 în loc de 02h. MASM, TASM și WASM, precum Emu8086, permit astfel de „libertăți”. Deși puteți scrie 02h - nu va exista nicio eroare.

Explicații pentru program:

.modelul minuscul– prima linie. Directiva .model definește modelul de memorie pentru un anumit tip de fișier. În cazul nostru, acesta este un fișier cu extensie COM, așa că alegem modelul mic, care combină cod, date și segmente de stivă. Modelul mic este conceput pentru a crea fișiere de tip COM.

.cod– a doua linie. Această directivă începe un segment de cod.

ORG 100h– a treia linie. Această comandă setează contorul programului la 100h, deoarece la încărcarea unui fișier COM în memorie, DOS alocă primii 256 de octeți blocului de date PSP ( numar decimal 256 este egal cu 100h hexazecimal). Codul programului se află numai după acest bloc. Toate programele care sunt compilate în fișiere de tip COM trebuie să înceapă cu această directivă.

începere: MOV AH, 02h– a 4-a linie. Eticheta de start este plasată înaintea primei comenzi din program și va fi folosită în directiva END pentru a indica cu ce comandă începe programul. Instrucțiunea MOV plasează valoarea celui de-al doilea operand în primul operand. Adică valoarea 02h este plasată în registrul AN. De ce se face asta? 02h este o funcție DOS care afișează un caracter pe ecran. Scriem un program pentru DOS, așa că folosim comenzile acestuia sistem de operare(OS). Și scriem această funcție (sau mai degrabă numărul ei) în registrul AH, deoarece întreruperea 21h folosește acest registru.

MOV DL, 41h– a 5-a linie. Codul caracterului „A” este introdus în registrul DL. Codul ASCII pentru caracterul „A” este 41h.

INT 21h– a 6-a linie. Aceasta este aceeași întrerupere 21h - comanda care provoacă functia sistemului DOS specificat în registrul AN (în exemplul nostru aceasta este funcția 02h). Comanda INT 21h este principalul mijloc de interacțiune între programe și OS.

INT 20h– a 7-a linie. Aceasta este o întrerupere care îi spune sistemului de operare să iasă din program și să transfere controlul către aplicația consolă. Dacă programul a fost deja compilat și lansat din sistemul de operare, comanda INT 20h ne va întoarce la sistemul de operare (de exemplu, la DOS).

END start– a 8-a linie. Directiva END încheie programul în timp ce indică momentul în care ar trebui să înceapă execuția acestuia.

Să ne amintim că directivele (pseudo-operatorii) sunt instrucțiuni pentru asamblator, acestea sunt procesate numai atunci când programul este asamblat (tradus). Iată câteva dintre directivele utilizate în mod obișnuit.

Directive privind definirea identificatorului

Atribuiți un identificator cu un nume dat unui text sau unei valori numerice (expresie). Formatul directivei:

nume EQU text

nume = valoare numerică (expresie)

Diferența dintre pseudo-operatorii EQU și =:

l EQU - atribuie o valoare permanent (nu poate fi schimbat), textul poate fi o expresie simbolică, numerică sau mixtă definind o constantă, adresă, alt nume simbolic, etichetă etc.;

l = - realizează atribuirea curentă (valoarea poate fi reatribuită, dar numai în timpul traducerii, desigur); atribuie numai expresie numerică, care conțin transformări matematice simple care vor fi efectuate în timpul translației (de exemplu: const + 1, 15H*4, 3*12/4 etc.).

Directive privind definirea datelor

Folosit pentru a identifica variabile și câmpuri de memorie. Formatul directivei

[nume] D* expresie [,expresie] [,...].

Cuvintele cheie D* ar putea fi:

l DB - definește octet (1 octet);

l DW - definiți un cuvânt (2 octeți);

l DD - definiți un cuvânt dublu (4 octeți);

l DQ - definiți 8 octeți;

l DT - definiți 10 octeți.

Directivele în cauză declară o variabilă (nume) sau atribuie valori inițiale câmpurilor (celulelor) de memorie; rezervă în memorie (cu atribuire ulterioară a valorii) unul sau mai mulți octeți - DB, cuvinte - DW, cuvinte duble- DD etc.

Expresia arată câte elemente de memorie trebuie alocate și ce date ar trebui să fie conținute acolo. Expresia ar putea fi:

l constanta:
const DB 56; const DW 1936; const DD 3FFH.
Asigurați-vă că luați în considerare intervalul și capacitatea unui octet, cuvânt etc.; deci, pentru DB constanta nu poate fi mai mare de 255, pentru DW - 65.535, pentru DD -



l 65 535 2 – 1 = 4 294 967 295;

l vector sau tabel:
tabel1 DB 30, 4, –15, 0, 0, 0, 56; tabelul 2 DW 1936, 3004, 56, 15.
Într-un pseudo-operator puteți plasa un șir de până la 132 de poziții și, în loc să repetați aceeași valoare de mai multe ori (0 în tabelul 1), puteți utiliza pseudo-operatorul DUP (duplicat):
tabel1 DB 30, 4, –15, 3 dup(0), 56);

l un șir de caractere:
str1 DB „Ați introdus prea multe număr mare";
str2 DB „Comandă proastă”;
în pseudo-operatorul DB linia poate conține 255 de caractere, în toate celelalte (DW, DD, DQ, DT) - doar 2 caractere.

l câmp gol:
pol 1 DB ?; pole2 DW 12 dup(?),
în același timp, nu se scrie nimic în elementele de memorie rezervate când programul este încărcat (nu se scrie 0, ca, de exemplu, în directiva pole3 DW 5 dup(0), ci celulele de memorie sunt pur și simplu rezervate);

l nume variabilă simbolică:
var1 DW disp; var2 DD vector
(o variabilă este definită de adresa alteia; nu este nevoie să specificați offset în directive, deoarece numele variabilei este perceput ca adresa sa). Această opțiune este potrivită, de exemplu, pentru stocarea adreselor celulelor de memorie, a etichetelor care pot fi referite într-un program (var1 DW disp), iar dacă variabila se află în același segment cu comanda de referință, atunci este suficient să specificați doar offset-ul ca adresa (2 octeți), adică vă puteți descurca cu DW; dacă variabila se află într-un alt segment, atunci trebuie să specificați atât segmentul, cât și offset-ul (4 octeți în total), adică ar trebui să utilizați DD (var2 DD vector);

l cu o expresie simplă:
fn1 DB 80*3; fn2 DW (disp) + 256, calculat, desigur, numai atunci când programul este tradus.

Directive pentru definirea segmentelor și procedurilor

Un segment este definit de pseudo-operatori:

segment_name segment

segname se termină

Într-un program, puteți utiliza 4 segmente (în funcție de numărul de registre de segmente) și pentru fiecare, specificați registrul de segment corespunzător folosind pseudo-operatorul ASSUME (asumați - atribuiți), de exemplu:

presupune CS:codeseg, DS:dataseg, SS:stackseg

Directiva ASSUME register_seg:seg_name [,..], în special, ASSUME cs:codeseg, specifică că registrul selectat pentru segmentul seg_name (codeseg) este CS.

Directiva ASSUME este urmată de explicitîncărcați adresa de început a segmentului de date în registrul DS:

Procedura este definită de pseudo-operatori:

nume_procedura proc...

nume_procedură endp

La definirea unei proceduri după cuvânt cheie proc trebuie să specifice atributul distanță aproape sau departe; dacă acest atribut nu este prezent, atunci valoarea implicită este aproape. De obicei, procedura ar trebui să se încheie cu o comandă ret (retur). Dacă o procedură este declarată ca fiind apropiată, atunci apelul trebuie făcut din același segment; dacă procfar, atunci din orice segment (în acest caz, comanda ret va scoate două cuvinte din stivă la întoarcere: pentru IP și pentru CS).

Directive privind controlul difuzării

Sunt mai multe dintre ele, cel mai des folosit este END. Directiva END marchează sfârșitul programului și îi spune asamblatorului unde să termine traducerea. Format: END [nume_program].

Proceduri de programare pentru lucrul cu dispozitive de intrare/ieșire

Procedurile I/O dintr-un PC sunt de obicei efectuate folosind întreruperi. Compoziția și utilizarea principalelor tipuri de întreruperi și funcții de serviciu ale întreruperii DOS 21H sunt discutate în lucrări. Mai jos vom discuta pe scurt problemele de programare a întreruperilor I/O numai pentru afișarea informațiilor pe afișaj și intrarea tastaturii. Problemele de ieșire a informațiilor către o imprimantă și de lucru cu fișiere sunt discutate în lucru.

Programarea afișajului

Setarea modurilor de operare și schimbul de date cu afișajul poate fi efectuată folosind întreruperile BIOS de tip 10H, iar datele pot fi transmise pe afișaj folosind întreruperi DOS tip 21H.

Operații video cu întrerupere DOS 21H

l Ieșire simbol pe ecran: AH = 2 sau AH = 6 și DL<>0FFh. Registrul DL trebuie să conțină codul ASCII al caracterului. Exemplu de fragment de program (ieșirea simbolului „C”):

mov DL, 43H; 43H este codul ASCII pentru caracterul C

l Ieșirea unui șir de caractere: AH = 9 (funcția cea mai frecvent utilizată). Registrele DS:DX trebuie să conțină adresa de pornire a șirului de caractere, care trebuie să se termine cu caracterul $. Un exemplu de fragment de program (afișând textul „ieșire un șir de caractere $”):

Text db "șir de caractere de ieșire $"

mov DX, text offset; aceasta este adresa liniei de ieșire

l I/O din fișier prin număr logic. Numerele logice standard ale fișierelor identifică tipul și dispozitivul I/O:

l 0 - intrare de la tastatură;

l 1 - ieșire pe ecranul de afișare;

l 2- afișează un mesaj de eroare;

l 3- I/O activat dispozitiv extern;

l 4- imprimare.

Funcția AH = 3Fh a întreruperii 21H este utilizată pentru intrare, funcția AH = 40h a întreruperii 21H este utilizată pentru ieșire. Registrul CX este pre-setat cu numărul de octeți de intrare/ieșire, iar registrul DX este pre-setat cu adresa de pornire a câmpului de memorie pentru I/O. Dacă procedura I/O se finalizează cu succes, indicatorul de transport CF este șters și numărul de octeți efectiv transferați este returnat în registrul AX. Dacă operațiunea eșuează, indicatorul CF este setat la 1 și un cod de eroare este scris în registrul AX.

Exemplul de mai jos conține un fragment de program de afișat pe ecran fisier text Text care conține 50 de octeți.

text db 50 dup(" ")

mov BX, 1; specificând dispozitivul de ieșire

mov CX, 50 ;indicând numărul de octeți care urmează să fie scos

mov DX, text offset; precizând adresa de pornire

; câmp de memorie care conține text

Directive de adunare

Compilatorul acceptă o serie de directive. Directivele nu sunt traduse direct în cod. În schimb, ele sunt folosite pentru a indica poziția în memoria programului, definiții macro, inițializarea memoriei etc. Toate directivele sunt precedate de un punct.

Lista directivelor este prezentată în tabelul următor.

Directivă Descriere
BYTE Rezervați octeți în RAM
CSEG Segment de program
D.B. Definiți octeți în flash sau EEPROM
DEF Atribuiți un nume simbolic unui registru
DISPOZITIV Determinați dispozitivul pentru care este compilat programul
DSEG Segment de date
DW Definiți cuvinte în flash sau EEPROM
ENDM, ENDMACRO Sfârșitul macro-ului
EQU Setați expresia constantă
ESEG Segmentul EEPROM
IEȘIRE Ieșiți din fișier
INCLUDE Atașați un alt fișier
LISTĂ Activați generarea înregistrării
LISTMAC Activați extinderea macrocomenzii în înregistrare
MACRO Începutul macro
NOLIST Dezactivați generarea înregistrării
ORG Setați poziția în segment
A STABILIT Setați echivalentul expresiei simbolice variabile

BYTE - rezerva octeți în RAM. Directiva BYTE rezervă octeți în RAM. Dacă doriți să vă puteți referi la o zonă de memorie alocată, directiva BYTE trebuie să fie precedată de o etichetă. Directiva preia un parametru necesar, care specifică numărul de octeți de alocat. Această directivă poate fi utilizată numai în segmentul de date (vezi directivele CSEG și DSEG). Octeții alocați nu sunt inițializați.

Sintaxă:

LABEL: expresie .BYTE

DSEG var1: .BYTE 1 ; rezervă 1 octet pentru var1

tabel: .BYTE tab_size ; rezervă tab_size octeți

Ldi r30,low(var1) ; Încarcă octetul mic al registrului Z

Ldi r31,high(var1) ; Încarcă octetul mare al registrului Z

Ld r1,Z ; Încarcă var1 în registrul 1

DB - definiți octeți în flash sau EEPROM. Directiva DB rezervă un număr extrem de important de octeți în memoria programului sau EEPROM. Dacă doriți să vă puteți referi la o zonă de memorie alocată, directiva DB trebuie să fie precedată de o etichetă. Directiva DB trebuie să aibă cel puțin un parametru.
Postat pe ref.rf

Parametrii trecuți directivei sunt o secvență de expresii separate prin virgule. Fiecare expresie trebuie să fie fie un număr din intervalul (-128..255), fie calculul trebuie să producă un rezultat în același interval, altfel numărul este trunchiat la un octet și FĂRĂ să emită avertismente.

Dacă o directivă primește mai mult de un parametru și segmentul de program curent este cel, parametrii sunt împachetati în cuvinte (primul parametru este octetul inferior). Dacă numărul de parametri este impar, atunci ultima expresie va fi trunchiată la un octet și scrisă ca un cuvânt cu octetul cel mai semnificativ egal cu zero, chiar dacă mai urmează o altă directivă DB.

Sintaxă:

LABEL: .DB expression_list

CSEG const: .DB 0, 255, 0b01010101, -128, 0xaa

const2: .DB 1,2,3

DW - definiți cuvinte în flash sau EEPROM. Directiva DW rezervă un număr extrem de important de cuvinte în memoria programului sau EEPROM. Dacă doriți să vă puteți referi la o zonă de memorie alocată, directiva DW trebuie să fie precedată de o etichetă. Directiva DW trebuie să aibă cel puțin un parametru.
Postat pe ref.rf
Această directivă trebuie plasată numai în segmentul de program (CSEG) sau în segmentul EEPROM (ESEG).

Parametrii trecuți directivei sunt o secvență de expresii separate prin virgule. Fiecare expresie trebuie să fie fie un număr din interval (-32768..65535), fie calculul trebuie să producă un rezultat în același interval, altfel numărul este trunchiat într-un cuvânt și FĂRĂ a emite avertismente.

Sintaxă:

LABEL: .DW expressionlist

varlist:═ .DW 0, 0xffff, 0b1001110001010101, -32768, 65535

eevarlst: .DW 0.0xffff,10

· Segmente

DSEG - segment de date. Directiva DSEG specifică începutul segmentului de date. Fișierul sursă poate consta din mai multe segmente de date, care sunt combinate într-un singur segment în timpul compilării. Segmentul de date constă de obicei numai din directive BYTE și etichete. Segmentele de date au propriile lor contoare de poziție de octeți. Directiva ORG trebuie utilizată pentru a plasa variabile într-o locație critică din RAM. Directiva nu are parametri.

Sintaxă:

ldi r30,low(var1) ; Încărcați octetul mic al registrului Z

ldi r31,high(var1) ; Încărcați octetul mare al registrului Z

ld r1,Z ; Încărcați var1 în registrul r1

CSEG - segment de program. Directiva CSEG definește începutul unui segment de program. Un fișier sursă poate consta din mai multe segmente de program, care sunt combinate într-un singur segment de program în timpul compilării. Segmentul de program este segmentul implicit. Segmentele de program au propriile lor contoare de poziție, care contează ca și cum mai degrabă decât octet cu octet. Directiva ORG ar trebui utilizată pentru a plasa codul și constantele într-o locație critică din segment. Directiva CSEG nu are parametri.

Sintaxă:

DSEG ; Începutul segmentului de date

vartab: .BYTE 4 ; Rezervă 4 octeți în RAM

CSEG; Începutul segmentului de cod

const: .DW 2 ; Plasați constanta 0x0002 în memoria programului

mov r1,r0 ; Efectuați acțiuni

ESEG - segment EEPROM. Directiva ESEG definește începutul segmentului EEPROM. Fișierul sursă poate consta din mai multe segmente EEPROM, care sunt combinate într-un singur segment în timpul compilării. Un segment EEPROM constă de obicei doar din directive DB, DW și etichetă. Segmentele EEPROM au propriile lor contoare de poziție de octeți. Directiva ORG trebuie utilizată pentru a plasa variabile într-o locație critică în EEPROM. Directiva nu are parametri.

Sintaxă:

DSEG ; Începutul segmentului de date

var1: .BYTE 1 ; rezerva 1 octet pentru var1

tabel: .BYTE tab_size ; rezerva tab_size octeți.

eevar1: .DW 0xffff ; inițializați 1 cuvânt în EEPROM

ORG - Setați poziția în segment. Directiva ORG setează contorul de poziție egal cu o valoare dată, care este transmisă ca parametru.
Postat pe ref.rf
Este important de menționat că pentru segmentul de date setează contorul de poziție în SRAM, pentru segmentul de program este contorul de program, iar pentru segmentul EEPROM este poziția în EEPROM. Dacă directiva este precedată de o etichetă (în aceeași linie), atunci eticheta este plasată la adresa specificată în parametrul directivei. Înainte de a începe compilarea, contorul de program și contorul EEPROM sunt egale cu zero, iar contorul RAM este egal cu 32 (deoarece adresele 0-31 sunt ocupate de registre). Vă rugăm să rețineți că contoarele de octeți sunt utilizate pentru RAM și EEPROM, iar contoarele de cuvinte sunt folosite pentru segmentul de program.

Sintaxă:

Expresia ORG

DSEG ; Începutul segmentului de date

ORG 0x37 ; Setați adresa SRAM la 0x37

variabilă: .BYTE 1 ; Rezervați un octet la adresa 0x37H

CSEG.ORG 0x10; Setați contorul de programe la 0x10

mov r0,r1 ; Această comandă va fi localizată la adresa 0x10

Sintaxă:

· Macrocomenzi

MACRO - începutul unei macrocomenzi. Definiția unei macrocomenzi începe cu directiva MACRO. Numele macro-ului este transmis directivei ca parametru. Când un nume de macrocomandă este întâlnit mai târziu în textul programului, compilatorul înlocuiește acest nume cu corpul macrocomenzii. O macrocomandă poate avea până la 10 parametri, care sunt accesați în corpul său prin @0-@9. Când sunt apelați, parametrii sunt listați separați prin virgule. Definiția macro se termină cu directiva ENDMACRO.

În mod implicit, doar apelul macro este inclus în listare pentru a extinde macro, este extrem de important să folosiți directiva LISTMAC. Macrocomanda din listă este afișată cu semnul +.

Sintaxă:

Nume macro macro MACRO

MACRO SUBI16; Începutul definiției macro

subi @1,low(@0) ; Scădeți octetul mic al parametrului 0 din parametrul 1

sbci @2,high(@0) ; Scădeți octetul mare al parametrului 0 din parametrul 2

CSEG; Începutul segmentului de program

SUBI16 0x1234,r16,r17 ; Scădeți 0x1234 din perechea r17:r16

ENDMACRO - sfârșitul macrocomenzii. Directiva definește sfârșitul unei definiții macro și nu acceptă niciun parametru. Pentru informații despre definirea macrocomenzilor, consultați directiva MACRO.

Sintaxă:

MACRO SUBI16; Pornirea unei definiții macro

subi r16,low(@0) ; Scădeți octetul mic al primului parametru

sbci r17,high(@0) ; Scădeți octetul înalt al primului parametru

LISTMAC - activați extinderea macrocomenzii în listă. După directiva LISTMAC, compilatorul va afișa conținutul macrocomenzii în listă. În mod implicit, lista arată doar apelul macro și parametrii trecuți.

Sintaxă:

MACRO MACX ; Definiție macro

adăugați r0,@0 ; Corpul macro

ENDMACRO ; Sfârșitul definiției macro

LISTMAC; Activați extinderea macrocomenzii

MACX r2,r1; Apelarea unei macrocomenzi (corpul macrocomenzii va fi afișat în listă)

· Expresii

EQU - setează expresia constantă. Directiva EQU atribuie o valoare unei etichete. Această etichetă poate fi folosită ulterior în expresii. O etichetă a cărei valoare este atribuită de această directivă nu trebuie să fie reatribuită și valoarea acesteia nu trebuie modificată.

Sintaxă:

EQU label = expresie

EQU io_offset = 0x23

EQU porta = io_offset + 2

CSEG; Începutul segmentului de date

clr r2 ; Ștergeți registrul r2

SET - Setează echivalentul simbolic variabil al expresiei. Directiva SET atribuie un nume fără sens. Acest nume trebuie folosit ulterior în expresii. Mai mult, spre deosebire de directiva EQU, valoarea numelui trebuie schimbată de o altă directivă SET.

Sintaxă:

SET nume = expresie

SET io_offset = 0x23

SET porta = io_offset + 2

CSE ; Începutul segmentului de cod

clr r2 ; Ștergeți registrul 2

out porta,r2 ; Scrieți în portul A

DEF - atribuiți un nume simbolic registrului. Directiva DEF permite referirea unui registru printr-un nume non-simbolic. Numele atribuit poate fi folosit în următoarea parte a programului pentru a se referi la acest registru. Un registru poate avea mai multe nume diferite. Numele simbolic trebuie reatribuit mai târziu în program.

Sintaxă:

DEF Symbolic_name = Înregistrare

ldi temp,0xf0 ; Încărcați 0xf0 în registrul temp (R16)

eor temp, ior; Registrele temp și ior sunt adăugate prin exclusiv sau

DEVICE - definiți dispozitivul. Directiva DEVICE vă permite să specificați pentru ce dispozitiv este compilat programul. Când se utilizează această directivă, compilatorul va emite un avertisment dacă se găsește o instrucțiune care nu este acceptată de acest microcontroler.
Postat pe ref.rf
De asemenea, va fi emis un avertisment dacă segmentul software sau segmentul EEPROM depășește dimensiunea permisă de dispozitiv. Dacă directiva nu este utilizată, atunci toate instrucțiunile sunt considerate valide și nu există restricții privind dimensiunea segmentelor.

Sintaxă:

DISPOZITIV AT90S1200 | AT90S2313 | AT90S2323 | AT90S2333 | AT90S2343 | AT90S4414 | AT90S4433 | AT90S4434 | AT90S8515 | AT90S8534 | AT90S8535 | ATtiny11 | ATtiny12 | ATtiny22 | ATmega603 | ATmega103

DISPOZITIV AT90S1200 ; AT90S1200 folosit

împinge r30 ; instrucțiunea va provoca un avertisment, AT90S1200 nu are

EXIT - ieșiți din fișier. Când compilatorul întâlnește o directivă EXIT, oprește compilarea fișierului. Dacă directiva este utilizată într-un fișier atașat (vezi directiva INCLUDE), atunci compilarea continuă din linia care urmează directivei INCLUDE. Dacă fișierul nu este imbricat, atunci compilarea se oprește.

Sintaxă:

IEȘIRE ; Ieșiți din acest fișier

INCLUDE - atașați un alt fișier. După ce a întâlnit o directivă INCLUDE, compilatorul deschide fișierul specificat în acesta, îl compilează până când fișierul se termină sau este întâlnită directiva EXIT, după care continuă să compilați fișierul inițial din linia care urmează directivei INCLUDE. Fișierul atașat poate conține și directive INCLUDE.

Sintaxă:

INCLUDE „nume fișier”

; fișier iodefs.asm:

EQU sreg = 0x3f ; Registrul de stare

EQU sphigh = 0x3e ; Indicator de stivă octet înalt

flux EQU = 0x3d ; Octet scăzut al indicatorului stivei

; fișierul incdemo.asm

INCLUDE iodefs.asm ; Atașați definiții de porturi

· Listări

LIST - activați generarea listelor. Directiva LIST îi spune compilatorului că este extrem de important să creeze o listă. Lista este o combinație de cod de asamblare, adrese și coduri operaționale. În mod implicit, generarea de liste este activată, dar această directivă este utilizată împreună cu directiva NOLIST pentru a obține liste ale părților individuale ale fișierelor sursă.

Sintaxă: .LIST

NOLIST - dezactivați generarea listelor. Directiva NOLIST îi spune compilatorului că este extrem de important să înceteze generarea de listări. Lista este o combinație de cod de asamblare, adrese și coduri operaționale. În mod implicit, generarea listelor este activată, dar trebuie să fie dezactivată de această directivă. În plus, această directivă trebuie utilizată împreună cu directiva LIST pentru a obține liste ale părților individuale ale fișierelor sursă

Sintaxă:.NOLIST

Exemplu: .NOLIST ; Dezactivați generarea înregistrării

INCLUDEȚI „macro.inc”; Fișierele atașate nu vor fi

INCLUDE "const.def"; afișat în listare

LISTA ; Activați generarea înregistrării

Directive de asamblare - concept și tipuri. Clasificarea și caracteristicile categoriei „Directive de asamblare” 2017, 2018.