Sunteți pe pagina 1din 39

Universitatea Lucian Blaga din Sibiu Catedra de Calculatoare i Automatizri

Arpad GELLERT Rodica BACIU

Programare n Limbaj de Asamblare

Aplicaii

Programare n limbaj de asamblare Lucrarea nr. 1. 1. Tipuri de date


BYTE (1 octet) Acest tip de date ocup 1 octet i poate fi reprezentat att n memoria intern, ct i ntr-un registru de 8 bii al procesorului. Interpretrile tipului byte pot fi: ntreg pe 8 bii cu sau fr semn; caracter ASCII.

Directiva pentru definirea datelor de acest tip este DB (Define Byte).

WORD (2 octei) Acest tip de date ocup 2 octei i poate fi reprezentat att n memoria intern, ct i ntr-un registru de 16 bii al procesorului. Interpretrile tipului word pot fi: ntreg pe 16 bii cu sau fr semn; secven de dou caractere ASCII; adres de memorie de 16 bii.

Directiva pentru definirea datelor de acest tip este DW (Define Word). Partea mai puin semnificativ este memorat la adrese mici. De exemplu dac presupunem ntregul 1234H la adresa 1000H, atunci octetul 34H se va gsi la adresa 1000H, iar octetul 12H la adresa 1001H. Similar, se memoreaz i secvenele de dou caractere ASCII.

DOUBLE-WORD (4 octei) Acest tip de date ocup 4 octei i poate fi reprezentat att n memoria intern, ct i ntr-o pereche de registre de 16 bii sau ntr-un registru de 32 de bii (la procesoarele de 32 de bii). Interpretrile tipului dword pot fi: ntreg pe 32 de bii cu sau fr semn; numr real n simpl precizie; adres de memorie de 32 de bii.

Directiva pentru definirea datelor de acest tip este DD (Define Double-Word). Valorile mai puin semnificative se memoreaz la adrese mici. n cazul adreselor pe 32 de bii, adresa de segment este memorat la adrese mari, iar deplasamentul (offset-ul), la adrese mici.

QUAD-WORD (8 octei) Acest tip de date ocup 8 octei i poate fi reprezentat att n memoria intern ct i ntr-o pereche de registre de 32 de bii (numai la procesoarele de 32 de bii). Interpretrile tipului qword pot fi: ntreg pe 64 de bii cu sau fr semn; numr real n dubl precizie;

Directiva pentru definirea datelor de acest tip este DQ (Define Quad-Word).

TEN-BYTES (10 octei) Acest tip de date ocup 10 octei i poate fi reprezentat att n memoria intern, ct i ntr-unul din registrele coprocesoarelor matematice. Interpretrile tipului tbyte pot fi: numr ntreg reprezentat ca secven de cifre BCD (mpachetate), cu semn memorat explicit; numr real n precizie extins.

Directiva pentru definirea datelor de acest tip este DT (Define Ten-Bytes).

2. Registrele procesorului 8086


Toate registrele procesorului 8086 sunt de 16 bii. O serie de registre (AX, BX, CX, DX) sunt disponibile i la nivel de octet, prile mai semnificative fiind AH, BH, CH i DH, iar cele mai puin semnificative, AL, BL, CL i DL. Denumirile registrelor sunt: AX-registru acumulator, BX-registru de baz general, CX-registru contor, DX-registru de date, BP-registru de baz pentru stiv (base pointer), SPregistru indicator de stiv (stack pointer), SI-registru index surs, DI-registru index destinaie. Registrul FLAGS cuprinde flagurile procesorului i ale bistabililor de condiie, iar registrul IP (instruction pointer) este contorul program. Denumirile registrelor de segment sunt: CS-registru de segment de cod (code segment), DS-registru de segment de date (data segment), SS-registru de segment de stiv (stack segment), ES-registru de segment de date suplimentar (extra segment). Perechea de registre (CS:IP) va indica adresa urmtoarei instruciuni, iar perechea (SS:SP) indic adresa vrfului stivei. Registrele DS i ES sunt folosite pentru a accesa date.

3. Moduri de adresare
Modurile de adresare specific modul n care se calculeaz adresa fizic a operandului aflat n memorie. Adresa fizic (AF) se calculeaz utiliznd: adresa de segment (AS) adic adresa de nceput a segmentului n care se afl operandul; adresa efectiv (AE) adica deplasamentul sau offset-ul operandului n cadrul segmentului. Adresarea imediat Operandul apare explicit n instruciune: Ex.: mov ax, 1 ; pune n AX valoarea 1 add bx, 2 ; adun la BX valoarea 2

Adresare direct Adresa efectiv a operandului este furnizat printr-un deplasament. Se consider registru de segment implicit registrul DS, n cazul n care nu se face o explicitare a registrului de segment. Ex.: .data VAL dw 1 .code .. mov bx, VAL ; pune n registrul bx valoarea 1 add cx, [100] ; adun la registrul cx ceea ce se afl n memorie, ; n segmentul de date la offset-ul 100. La asamblare, VAL se va nlocui cu deplasamentul n cadrul segmentului de date. Valoarea 100 este offset explicit.

Adresare indirect (prin registre) Adresa efectiv a operatorului este dat de coninutul registrelor BX, SI sau DI. Registrul de segment implicit este DS. 3

Ex.:

mov mov add

ax, [bx] [di], cx byte ptr [si], 2

; pune n AX coninutul locaiei de memorie de la adresa dat de BX ; memoreaz coninutul lui CX la adresa dat de registrul DI ; adun valoarea 2 la octetul aflat la adresa dat de SI

La ultima instruciune, operatorul byte ptr este absolut necesar altfel nu s-ar cunoaste tipul operandului (octet, cuvnt) la care se adun 2.

Adresare bazat sau indexat Adresa efectiv a operandului din memorie se obine adunnd la unul din registrele de baz (BP sau BX) sau la unul din regitrii index (SI sau DI) un deplasament constant de 8 sau 16 bii. Registrul de segment implicit este DS (pentru BX, SI) i SS (pentru BP). Ex.: .data VAL dw 10 dup (0) .code . mov bx, 5 mov ax, VAL[bx] mov ax, bx[VAL] mov ax, [bx+VAL] mov ax, [bx].VAL Instruciunile anterioare pun n registrul AX cuvntul din memorie aflat la offset-ul VAL+5. Observaii: mov mov

ax, [bx] ax, [bp]

; adresare indirect ; adresare bazat cu deplasament nul, ; deoarece registrul BP nu se folosete n adresarea indirect

Adresare bazat i indexat Adresa efectiv este format prin adresarea unuia din registrele de baz (BX sau BP) cu unul din registrele index (SI sau DI) i cu un deplasament de 8 sau 16 bii. Registrele de segment implicite sunt DS pentru BX cu SI sau DI i SS pentru BP cu SI sau DI. Ex.: mov ax, [bx][si] mov ax, [bx+si+7] mov ax, [bx+si].7 mov ax, [bp][di][7] Observaii: la toate modurile de adresare se poate utiliza un registru de segment explicit, n felul urmtor: mov bx, ds:[bp+7] ; adresare bazat mov ax, cs:[si][bx+3] ; adresare bazat i indexat mov ax, ss:[bx] ; adresare indirect.

4. Aplicaii
Se cere obinerea fiierului executabil pentru urmtoarea poriune de cod i rularea apoi pas cu pas. .model small .stack 100 .data tabel tabel1 tabel2 tabel3 tabel4 .code

db 1, 2, 3, 4, 5, 10 dup(?) dw 1, 2, 3, 12H, 12 dd 1, 2, 1234H dq 1, 2, 12345678H dt 1, 2,, 1234567890H

start:

mov mov mov mov mov mov mov mov mov mov mov mov mov mov mov mov mov mov mov mov mov mov int

ax, @data ds, ax ax, 14h ;adresare imediat ax, 14 al, tabel ;adresare direct al, tabel[1] ;adresare direct ax, word ptr tabel ;adresare direct - operatorul ptr este necesar, ax, word ptr tabel[2] ;tabel fiind definit cu directiva DB bx, offset tabel al, [bx+1] ;adresare indirect al, [bx] ;adresare indirect bx, 5 al, tabel[bx] ;adresare bazat si, 1 al, [bx][si] ;adresare bazat i indexat si, 6 byte ptr [bx][si],2 ;adresare bazat i indexat bp, offset tabel al, [bp] ;adresare bazat cu deplasament nul byte ptr ds:[bp][si][1], 7 word ptr ds:[bp][si][1], 19H ;adresare bazat i indexat ah, 4ch 21h

end start Indicaii Pentru obinerea fiierului executabil se va utiliza mediul Borland C sau Borland Pascal de dezvoltare a programelor. Fazele de obinere a programului executabil din fiierul ASCII salvat cu extensia *.asm sunt: asamblarea: tasm *.asm/zi/la - zi este folosit pentru includerea opiunilor de depanare; - la este folosit pentru obinerea unui fiier listing util n depanare; linkeditarea: tlink *.obj/v - v este folosit pentru includerea opiunilor de depanare; depanarea: td *.exe Dup obinerea fiierului executabil acesta va fi executat pas cu pas n mediul de depanare. Se va vizualiza coninutul memoriei (View/Dump) i al registrelor (View/Registers) nainte i dup executarea fiecrei instruciuni. Se va verifica pentru fiecare dat definit numrul octeilor alocai n memorie i respectarea conveniei Intel pentru memorarea acestora.

Probleme propuse spre rezolvare 1. 2. 3. 4. n aplicaia de mai sus, care sunt instruciunile care modific coninutul unei locaii de memorie? n aplicaia de mai sus s se determine care este adresa la care se ncarc segmentul de date. Pentru aceasta se vor executa primele dou instruciuni ale programului. Pentru aplicaia de mai sus s se specifice pentru fiecare zon a programului (date, cod, stiv) care este adresa de segment i care este adresa de offset la nceputul execuiei programului. Pentru aplicaia de mai sus s se determine care este adresa fizic a locaiei de memorie la care se memoreaz valoarea 5 din tabel. Fiecare student va determina aceast adres pentru contextul de pe calculatorul pe care lucreaz. Pentru aplicaia de mai sus s se determine ci octei s-au alocat pentru memorarea datelor. S se verifice i numrnd octeii n fereastra Dump. Specificai adresa efectiv i adresa fizic a locaiei de memorie modificat de instruciunile: mov byte ptr [bx][si], 2 mov byte ptr ds:[bp][si][1], 7 mov word ptr ds:[bp][si][1], 19H Motivai apariia valorii 00H (n loc de 01H) n registrul AL, n urma execuiei instruciunii: mov al, [bp]. 5

5. 6.

7.

Programare n limbaj de asamblare Lucrarea nr. 2. 1. Definirea i iniializarea datelor


Constante O constant este un simplu nume asociat unui numr i nu are caracteristici distinctive. Tip binare octale zecimale hexazecimale ASCII Reguli secvene de 0, 1 urmate de B sau b secvene de 07 urmate de O sau Q secvene de 09 opional urmate de D sau d secvene de 09 i AF urmate de H sau h ir de caractere Exemple 11B, 1011b 777Q, 567O 3309, 1309D 55H, 0FEh BC

Constantele pot apare explicit n program: mov ah, 5 mov ax, 256 sau ca valori asignate unor simboluri (constante simbolice): five equ 5 mov ah, five

Variabile Variabilele identific datele manipulate, formnd operanzi pentru instruciuni. Se definesc utiliznd directivele DB, DW, DD, DQ, DT. Aceste directive aloc i iniializeaz memoria n uniti de octei, cuvinte, dublu cuvinte, etc. nume directiv lista_de_valori

Numelui variabilei i se asociaz urmtoarele atribute: segment: variabil asociat cu segmentul curent offset: variabil asignat offset-ului curent fa de nceputul segmentului tip: 1 octet pentru DB, 2 octei pentru DW, etc. Lista de valori poate cuprinde: expresie constant caracterul ? pentru iniializri nedeterminate expresie de tip adres un ir ASCII cu mai mult de dou caractere (numai cu directiva DB) expresie DUP (expresie1 [, expresie2, ])

Etichete Etichetele identific cod executabil, formnd operanzi pentru CALL, JMP sau salturi condiionate. O etichet poate fi definit: prin numele etichetei urmat de caracterul : - se definete astfel o etichet de tip near nume_etichet: Ex.: eticheta: mov ax, bx prin directiva LABEL, cu forma general nume label tip Dac ceea ce urmeaz reprezint instruciuni (cod), tipul etichetei va fi NEAR sau FAR i eticheta va fi folosit ca punct int n instruciuni de tip JMP/CALL. Daca ceea ce urmeaz reprezint definiii de date, tipul etichetei va fi BYTE, WORD, DWORD, etc.

De exemplu, n urma definiiei: alfab label byte alfaw dw 1234H o instruciune de forma mov al, alfab va pune n AL octetul mai puin semnificativ al cuvntului (34H). prin directiva PROC, numele procedurii fiind interpretat ca o etichet cu tipul derivat din tipul procedurii (NEAR sau FAR). Forma general a unei proceduri este: nume_proc proc tip nume_proc endp

2. Instruciuni de transfer
instruciuni de transfer generale: MOV, XCHG, PUSH, POP instruciuni de transfer specifice acumulatorului: IN, OUT, XLAT instruciuni de transfer specifice adreselor: LEA, LDS, LES instruciuni de transfer specifice indicatorilor de condiii: LAHF, SAHF, PUSHF, POPF

2.1. Instruciuni de transfer generale Instruciunea MOV (Move Data - Transfer date) Forma general este: mov dest, sursa

; dest src

Urmtoarele operaii sunt ilegale: sursa i destinaia nu pot fi ambele operanzi n memorie; nu pot fi folosite registrele FLAGS i IP; operanzii nu pot avea dimensiuni diferite; registrul CS nu poate aprea ca destinaie; nu pot fi transferate date imediate ntr-un registru de segment; operanzii nu pot fi simultan registre de segment Exemple: mov ax, bx mov al, ch mov val[bx][si], al mov byte ptr [bx+100], 5 O instruciune de forma: .data ALFA db 1 .code mov al, ALFA ncarc n AL coninutul locaiei de memorie ALFA. Dac se dorete ncrcarea adresei efective a variabilei ALFA, se poate folosi operatorul OFFSET: mov bx, offset ALFA

Instruciunea XCHG (Exchange Data - Interschimb date) Forma general este: XCHG dest, sursa Restricii:

; sursa dest

cel puin un operand trebuie s fie n registru; registrele de segment nu pot fi operanzi.

Exemple: xchg

ax, bx

Secven de instruciuni pentru schimbarea coninutului a dou locaii de memorie: mov ax, alfa1 xchg ax, alfa2 mov alfa1,ax

Instruciunea PUSH (Push Data - Salveaz date n stiv) Forma general: push sursa SP SP-2 SS: [SP+1] high(sursa) SS:[SP] low(sursa) Sursa pote fi un operand pe 16 bii aflat n: registru general de 16 bii registru de segment locaie de memorie Exemple: push push push push bx beta [bx] [bp+5] ; SS:[SP] BX ; coninutul memoriei de la adresa beta se memoreaz n stiv ; SS:[SP] DS:[BX] ; SS:[SP] SS:[BP+5]

Instruciunea POP (Pop Data - Ref date din stiv) Forma general: pop dest high(dest) SS: [SP+1] low(sursa) SS:[SP] SP SP+2 Destinaia pote fi un operand pe 16 bii aflat n: registru general de 16 bii registru de segment locaie de memorie Exemple: pop pop pop cx es:[di] [bp+5] ; CX SS:[SP] ; ES:DI SS:[SP] ; SS:[BP+5] SS:[SP]

Accesul la informaiile memorate n stiv se poate face fr descrcarea acesteia, utilizd adresarea bazat: mov bp, sp ; baza stivei push ax ; SP BP-2 push bx ; SP BP-4 mov ax, [bp-2] mov bx, [bp-4]

2.2. Instruciuni de transfer specifice acumulatorului Instruciunea IN (Input Data - Citete date de la port de intrare) Forma general este: in dest, port Instruciunea transfer un octet sau un cuvnt de la un port de intrare n acumulator (AL sau AX). Port poate fi registrul DX, sau o constant n intervalul 0255.

Instruciunea OUT (Output Data - Scrie date la port de ieire) Forma general este: out port, sursa Instruciunea transfer un octet sau un cuvnt din registrul AL sau AX la un port de ieire. Exemple: in in

al, 0f8h al, 0f9h

; citire stare de la un echipament ; citire date de la acelai echipament

Instruciunea XLAT (Translate - Translateaz) Instruciunea nu are operanzi, iar semnificaia este: AL DS:[BX+AL] Adic aduce n AL coninutul octetului de la adresa efectiv [BX+AL].

2.3. Instruciuni de transfer specifice adreselor Instruciunea LEA (Load Effective Address - ncarc adresa efectiv) Forma general este: LEA registru, sursa ncarc adresa efectiv a operandului surs n registrul specificat. Sursa este un operand aflat n memorie. Exemple: lea lea

bx, alfa di, alfa[bx][si]

; echivalent cu instruciunea mov bx, offset alfa

Instruciunile LDS (Load Data Segment - ncarc DS) i LES (Load Extra Segment - ncarc ES) Forma general este: lds reg, sursa les reg, sursa n care reg este un registru general de 16 bii, iar sursa este un operand de tip double-word aflat n memorie, care conine o adres complet de 32 de bii. Aceast adres se ncarc n perechea DS:reg, respectiv ES:reg, astfel nct cuvntul mai puin semnificativ (adresa efectiv) va fi n registrul reg, iar cuvntul mai semnificativ (adresa de segment) va fi n DS(ES).

Exemple: .data x db 10 y db 15 adr_x dd x adr_y dd y .code ... lds si, adr_x les di, adr_y mov byte ptr [si], 20 ; valoarea 20 se memoreaz n locul valorii 10 mov byte ptr es:[di], 30 ; valoarea 30 se memoreaz n locul valorii 15 2.4. Instruciuni de transfer specifice indicatorilor de condiie Instruciunea LAHF (Load AH with FLAGS - ncarc AH cu FLAGS) AH FLAGS0:7 Instruciunea SAHF (Store AH into FLAGS - Depune AH n FLAGS) FLAGS0:7 AH Instruciunea PUSHF (Push Flags - Salveaz FLAGS n stiv) SP SP-2 SS: [SP+1] high(FLAGS) SS:[SP] low(FLAGS) Instruciunea POPF (Pop Flags - Reface FLAGS din stiv) high(FLAGS) SS: [SP+1] low(FLAGS) SS:[SP] SP SP+2

; adr_x este adresa valorii x (adresde tip pointer) ; adr_y este adresa valorii y (adresde tip pointer)

3. Aplicaii
1. Se cere rularea pas cu pas a urmtorului program: .model small .stack 100 .data tabc db '0123456789ABCDEF' .code start: mov mov mov repet: mov push xlat call pop inc cmp jz jmp afisare proc mov mov int mov mov int ax,@data ds,ax al,0 bx,offset tabc ax afisare ax al al,10H sfarsit repet dl,al ah,2h 21h dl,' ' ah,2h 21h

;iniializeaz AL ;pune n BX adresa efectiv tabc ;salveaz AL n stiv ;pune n AL octetul de la adresa efectiv [BX+AL] ;apelul procedurii afisare

;se verific dac s-au afiat toate caracterele

;pune n DL codul caracterului care trebuie afiat ;funcia DOS pentru afiarea caracterului din DL

10

ret afisare endp sfarsit: mov int end

ax,4c00h 21h start

;funcia DOS de ieire n sistemul de operare

2. De ce este necesar salvarea n stiv a registrului AX, iar apoi restaurarea ei? 3. Modificai programul de mai sus pentru determinarea ptratului unui numr din intervalul 0-15. 4. Se cere rularea pas cu pas a urmtorului program: .model small .stack 100 .data adr1 dw 1234h adr2 dw 5678h adr3 dw 9012h adr4 dw 3456h tabela dd adr1, adr2, adr3, adr4 .code start: mov ax, @data mov ds, ax mov cx, 1 mov bx, cx add bx, bx add bx, bx les di, tabela[bx] mov ax, es:[di] mov ah, 4ch int 21h end start 5. Modificai programul de mai sus astfel nct s fie pus n AX valoarea care se afl la adr4. 6. Care din instruciunile urmtoare sunt corecte? mov al, si mov ds, es mov ax, ip mov bl, al mov cs, 23H 7. Care este efectul urmtoarei secvene de instruciuni? .data alfa db 14H tabel db 0A1H, 10, 0AFH, 23Q, 1111B, 0011B .code lea bx, tabel mov si, 3 mov al, [bx][si] 8. Care este coninutul locaiei alfa dup executarea urmoarei secvene de instruciuni? .data alfa db 23h beta db 43h .code mov al, alfa xchg al, beta mov alfa, al

11

Programare n limbaj de asamblare Lucrarea nr. 3.

Instruciuni aritmetice i logice


instruciuni specifice adunrii: ADD, ADC, INC, DAA, AAA instruciuni specifice scderii: SUB, SBB, DEC, NEG, CMP, DAS, AAS instruciuni specifice nmulirii: CBW, CWD, MUL, IMUL, AAM instruciuni specifice mpririi: DIV, IDIV, AAD instruciuni logice: NOT, AND, TEST, OR, XOR instruciuni de deplasare: SHL, SAL, SHR, SAR instruciuni de rotaie: ROL, RCL, ROR, RCR

1.

Instruciuni specifice adunrii

Instruciunea ADD (Add - Adun) ADD dest, sursa dest dest + sursa Instruciunea ADC (Add with Carry - Adun cu transport) ADC dest, sursa dest dest + sursa + CF Instruciunea INC (Increment - Incrementeaz) INC dest dest dest + 1 Instruciunea DAA (Decimal Adjust for Addition - Corecie zecimal dup adunare) Instruciunea nu are operanzi i efectueaz corecia zecimal a acumulatorului AL, dup o adunare cu operanzi n format BCD mpachetat. S considerm, de exemplu, adunarea valorilor BCD 65 i 17. Aceste valori se reprezint prin octeii 65H i 17H. n urma adunrii, se obine rezultatul 7CH, care este incorect ca rezultat BCD. Operaia de corecie conduce la rezultatul 82H, ceea ce reprezint suma BCD a celor dou valori. Instruciunea AAA (ASCII Adjust for Addition - Corecie ASCII dup adunare) Instruciunea nu are operanzi i efectueaz corecia acumulatorului AX, dup operaii de adunare cu operanzi BCD despachetai (o cifr BCD pe un octet). S considerm, de exemplu, adunarea valorilor 0309H i 0104H, care ar corespunde valorilor BCD despachetate 39 i 14. n urma adunrii, se obine rezultatul 040DH. Instruciunea AAA corecteaz acest rezultat la 0503H care este suma BCD a celor dou valori.

2.

Instruciuni specifice scderii

Instruciunea SUB (Substract - Scade) SUB dest, sursa dest dest - sursa Instruciunea SBB (Substract with Borrow - Scade cu mprumut) SBB dest, sursa dest dest - sursa - CF Instruciunea DEC (Decrement - Decrementeaz) DEC dest dest dest - 1

12

Instruciunea NEG (Negate - Schimb semnul) NEG dest dest 0 - dest Instruciunea CMP (Compare - Compar) CMP dest, sursa Execut scderea temporar dest - sursa fr a modifica vreun operand, dar cu poziionarea bistabililor de condiie (FLAGS) Instruciunea DAS (Decimal Adjust for Substraction - Corecie zecimal dup scdere) Instruciunea nu are operanzi i efectueaz corecia zecimal a acumulatorului AL, dup o scdere cu operanzi n format BCD mpachetat. S considerm, de exemplu, scderea valorilor BCD 52 i 24. Operaia de corecie conduce la rezultatul 28H (52-24=28). Instruciunea AAS (ASCII Adjust for Substraction - Corecie ASCII dup scdere) Instruciunea nu are operanzi i efectueaz corecia acumulatorului AX, dup operaii de scdere cu operanzi BCD despachetai (o cifr BCD pe un octet). S considerm, de exemplu, scderea valorilor 0502H i 0204H. Instruciunea AAS corecteaz rezultatul la 0208H.

3. Instruciuni specifice nmulirii Instruciunea CBW (Convert Byte to Word - Convertete octet la cuvnt) Extinde bitul de semn din AL la ntreg registrul AH, obinndu-se astfel o reprezentare a lui AL pe 2 octei. Instruciunea CWD (Convert Word to DoubleWord - Convertete cuvnt la dublu-cuvnt) Extinde bitul de semn din AX la ntreg registrul DX, obinndu-se astfel o reprezentare a lui AX pe 4 octei. Instruciunea MUL (Multiply - nmulete fr semn) MUL sursa AH:AL AL * sursa (dac sursa este pe octet) DX:AX AX * sursa (dac sursa este pe 2 octei) Instruciunea IMUL (Integer Multiply - nmulete cu semn) IMUL sursa Este similar cu instruciunea MUL. Deosebirea este c operaia de nmulire se face considernd operanzii numere cu semn. Instruciunea AAM (ASCII Adjust for Multiply - Corecie ASCII dup nmulire) Instruciunea nu are operanzi i efectueaz corecia acumulatorului AX, dup o nmulire pe 8 bii cu operanzi BCD despachetai (o cifr BCD pe un octet). S considerm, de exemplu, nmulirea valorilor 5 i 9. Instruciunea AAM corecteaz rezultatul 2DH la 0405H.

4.

Instruciuni specifice mpririi

Instruciunea DIV (Divide - mparte fr semn) DIV sursa Dac sursa este pe octet: AL AX / sursa AH AX mod sursa Dac sursa este pe 2 octei: AX DX:AX / sursa DX DX:AX mod sursa Instruciunea IDIV (Integer Divide - mparte cu semn) IDIV sursa Este similar cu instruciunea DIV. Deosebirea este c operaia de mprire se face considernd operanzii numere cu semn.

13

Instruciunea AAD (ASCII Adjust for Division - Corecie ASCII nainte de mprire)) Instruciunea nu are operanzi i efectueaz corecia acumulatorului AX. Operaia de corecie trebuie fcut nainte de mprirea unui numr BCD pe 2 octei la un numr BCD pe un octet.

5.

Instruciuni logice

Instruciunea NOT (Not - Negare logic bit cu bit) NOT dest Instruciunea AND (And - i logic bit cu bit) AND dest, sursa Instruciunea TEST (Test - Testeaz) TEST dest, sursa Efectul este execuia unei operaii AND ntre cei doi operanzi, fr a se modifica destinaia, dar cu poziionarea flagurilor la fel ca la instruciunea AND. Instruciunea OR (Or - Sau logic bit cu bit) OR dest, sursa Instruciunea XOR (Exclusive Or - Sau-exclusiv bit cu bit) XOR dest, sursa

6.

Instruciuni de deplasare

Instruciunea SHL/SAL (Shift Logic/Arithmetic Left - Deplaseaz logic/aritmetic la stnga) SHL operand, contor SAL operand, contor Bitul cel mai semnificativ trece n CF, dup care toi biii se deplaseaz la stnga cu o poziie. Bitul cel mai puin semnificativ devine 0. Numrul operaiilor este dat de contor. Instruciunea SHR (Shift Logic Right - Deplaseaz logic la dreapta) SHR operand, contor Bitul cel mai puin semnificativ trece n CF, dup care toi biii se deplaseaz la dreapta cu o poziie. Bitul cel mai semnificativ devine 0. Numrul operaiilor este dat de contor. Instruciunea SAR (Shift Arithmetic Right - Deplaseaz aritmetic la dreapta) SAR operand, contor Singura diferen fa de instruciunea SHR, este c se conserv bitul de semn, mai precis, completarea dinspre stnga se face cu bitul de semn.

7.

Instruciuni de rotire

Instruciunea ROL (Rotate Left - Rotete la stnga) ROL operand, contor Bitul cel mai semnificativ trece att n CF, ct i n bitul cel mai puin semnificativ, dup ce toi biii s-au deplasat la stnga cu o poziie. Numrul operaiilor este dat de contor. Instruciunea RCL (Rotate Left through Carry- Rotete la stnga prin carry) RCL operand, contor Bitul cel mai semnificativ trece n CF, toi biii se deplaseaz la stnga cu o poziie, iar CF original trece n bitul cel mai puin semnificativ. Numrul operaiilor este dat de contor. Instruciunea ROR (Rotate Right - Rotete la dreapta) ROR operand, contor Bitul cel mai puin semnificativ trece att n CF, ct i n bitul cel mai semnificativ, dup ce toi biii s-au deplasat la dreapta cu o poziie. Numrul operaiilor este dat de contor.

14

Instruciunea RCR (Rotate Right through Carry- Rotete la dreapta prin carry) RCR operand, contor Bitul cel mai puin semnificativ trece n CF, toi biii se deplaseaz la dreapta cu o poziie, iar CF original trece n bitul cel mai semnificativ. Numrul operaiilor este dat de contor.

Aplicaii
1. Care este coninutul registrului AL dup executarea urmtoarei secvene de instruciuni: mov al, 10011110b mov cl, 3 rol al, cl Care va fi coninutul registrului CX dup executarea urmtoarei secvene de instruciuni: mov bx, sp mov cx, 2134H push cx mov byte ptr ss:[bx-2], 22H pop cx Care este coninutul registrului AX dup executarea urmtoarei secvene de instruciuni: mov cl, 4 mov ax, 0702H shl al, cl shr ax, cl Care este coninutul registrului AX dup executarea urmtoarei secvene de instruciuni: mov cx, 1234H push cx mov bx, 2359H push bx mov ax, 4257H mov bp, sp mov byte ptr [bp], al pop ax S se scrie un program care adun numerele 145A789FH i 92457ABCH, afind rezultatul pe ecran. S se scrie un program care adun dou numere n format BCD mpachetat. Fiecare din cele dou numere are 4 cifre. Numerele sunt memorate n zona de date. Programul afieaz rezultatul adunrii. S se scrie un program care adun dou numere n format BCD despachetat. Fiecare din cele dou numere are 4 cifre. Numerele sunt memorate n zona de date. Programul afieaz rezultatul adunrii. S se scrie un program care afieaz pe ecran ptratul unui numr. Se va folosi instruciunea XLAT.

2.

3.

4.

5. 6. 7. 8.

15

Programare n limbaj de asamblare Lucrarea nr. 4.

Instruciuni de apel de procedur i de salt


Forma general pentru definirea unei proceduri este: nume_proc PROC [FAR | NEAR] RET nume_proc ENDP unde nume_proc este numele procedurii, iar parametrii opionali FAR sau NEAR indic tipul procedurii. Procedurile sunt de dou tipuri: FAR i NEAR. O procedur FAR poate fi apelat i din alte segmente de cod dect cel n care este definit, pe cnd o procedur NEAR poate fi apelat numai din segmentul de cod n care este definit. Dac se omit parametrii FAR sau NEAR, tipul procedurii este dedus din directivele simplificate de definire a segmentelor (modelul de memorie folosit). De exemplu , modelul LARGE presupune c toate procedurile sunt implicit de tip FAR. n mod corespunztor, exist apeluri de tip FAR, respectiv NEAR, precum i instruciuni de revenire de tip FAR, respectiv NEAR. Instruciunea RET (Return) provoac revenirea n programul apelant; tipul instruciunii este dedus din tipul procedurii (NEAR sau FAR). Putem folosi o instruciune de revenire explicit: RETN (Return Near) sau RETF (Return Far).

1.

Apelul procedurilor i revenirea din proceduri

Instruciunea CALL (Apel de procedur) CALL nume_proc CALL FAR PTR nume_proc CALL NEAR PTR nume_proc n primul caz, tipul apelului este dedus din tipul procedurii, iarn celelalte este specificat explicit (FAR sau NEAR). Tipul apelului trebuie s coincid cu tipul procedurii i cu tipul instruciunilor Return din interiorul procedurii, altfel se ajunge la funcionri defectuoase ale programului. n cazul unui apel de procedur de tip NEAR, se salveaz n stiv coninutul registrului IP, care reprezint adresa de revenire, iar apoi n IP se ncarc adresa primei instruciuni din procedur. n cazul unui apel de tip FAR, se salveaz n stiv CS:IP, adresa complet de revenire (pe 32 de bii), iar apoi n CS:IP se ncarc adresa primei instruciuni din procedur. Instruciunea RET (Return - Revenire din procedur) RET RETF RETN n primul caz, tipul tipul instruciunii este dedus din tipul procedurii. n cazul unei reveniri de tip NEAR, se reface registrul IP din stiv, astfel se transfer controlul la instruciunea care urmeaz instruciunii CALL care a provocat apelul procedurii. n cazul unei reveniri de tip FAR, se reface din stiv perechea de registre CS:IP. Instruciunea JMP (Jump - Salt) JMP tinta JMP SHORT PTR tinta JMP NEAR PTR tinta JMP FAR PTR tinta n primul caz, tipul saltului este dedus din atributele expresiei care precizeaz inta. inta specific adresa de salt i poate fi o etichet sau o expresie. Exist trei tipuri de instruciuni de salt: SHORT - adresa int se afl la o adres n domeniul [-127, +127] fa de adresa instruciunii de salt; NEAR - adresa int este n acelai segment de cod cu instruciunea de salt; FAR - adresa int poate fi n alt segment de cod fa de instruciunea de salt.

16

2.

Tipuri de salt/apel

JMP/CALL direct Operandul care se afl n formatul instruciunii este o etichet care identific adresa int. Poate fi de dou tipuri: salt/apel direct intrasegment (NEAR) - eticheta este n acelai segment de cod cu instruciunea JMP/CALL; salt/apel direct intersegment (FAR) - eticheta poate fi definit i n alt segment de cod dect cel care conine instruciunea JMP/CALL. JMP/CALL indirect Operandul care apare n formatul instruciunii reprezint o adres de memorie. Poate fi de dou tipuri: salt/apel indirect intrasegment (NEAR), cu forma general JMP/CALL expr n care expr precizeaz adresa efectiv a intei i poate fi un registru, o variabil de tip WORD, sau un cuvnt din memorie; salt/apel indirect intersegment (FAR), cu forma general JMP/CALL expr n care expr precizeaz adresa complet a intei i poate fi o variabil de tip DWORD, sau un dublucuvnt din memorie.

3.

Instruciuni de salt condiionat

Instruciunile din aceast categorie implementeaz salturi condiionate de valoarea unor bistabili (FLAGS). Dac condiia nu este ndeplinit, saltul nu are loc, deci execuia continu cu instruciunea urmtoare. Toate instruciunile de salt condiionat sunt de tip SHORT, ceea ce nseamn c adresa int trebuie s fie la o distan cuprins ntre -127 i +127 de octei fa de instruciunea de salt. n tabelul urmtor se prezint instruciunile de salt condiionat: Instruciune JE, JZ JL, JNGE JLE, JNG JB, JNAE, JC JBE, JNA JP, JPE JO JS JNE, JNZ JNL, JGE JNLE, JG JNB, JAE, JNC JNBE, JA JNP, JPO JNO JNS Condiie de salt ZF = 1 SF OF SF OF sau ZF = 1 CF = 1 CF = 1 sau ZF = 1 PF = 1 OF = 1 SF = 1 ZF = 0 SF = OF SF = OF i ZF = 0 CF = 0 CF = 0 i ZF = 0 PF = 0 OF = 0 SF = 0 Interpretare Zero, Equal Less, Not Greater or Equal Less or Equal, Not Greater Below, Not Above or Equal, Carry Below or Equal, Not Above Parity, Parity Even Overflow Sign Not Zero, Not Equal Not Less, Greater or Equal Not Less or Equal, Greater Not Below, Above or Equal, Not Carry Not Below or Equal, Above Not Parity, Parity Odd Not Overflow Not Sign

La comparaiile cu semn folosim GREATER i LESS, iar la comparaiile fr semn folosim ABOVE i BELOW. Uneori este necesar s folosim instruciuni de salt condiionat la etichete care ies n afara domeniului [-127, +127] fa de instruciunea curent. n aceast situaie nlocuim saltul pe o condiie direct departe cu un salt pe condiia negat aproape i cu un salt necondiionat departe. n urmtorul exemplu, eticheta et1 se afl n afara domeniului, astfel instruciunea: JE et1 se nlocuiete cu: JNE et2 JMP et1 et2:

17

4.

Instruciuni pentru controlul buclelor de program

Instruciunea JCXZ (Jump if CX is Zero - Salt dac CX este zero) JCXZ eticheta Eticheta trebuie s se afle n domeniul [-127, +127] fa de instruciunea curent. Se face salt la eticheta specificat dac CX conine valoarea 0. Instruciunea LOOP (Ciclare) LOOP eticheta Aceast instruciune este, de fapt, un salt condiionat de valoarea registrului CX. Cu alte cuvinte, se decrementeaz CX i, dac acesta este diferit de zero, se sare la eticheta specificat. Eticheta trebuie s se afle n domeniul [-127, +127] fa de instruciunea curent. Instruciunea LOOPZ/LOOPE (Loop While Zero/Equal - Cicleaz ct timp este zero/egal) LOOPZ eticheta LOOPE eticheta Se decrementeaz CX i, dac acesta este diferit de zero i ZF este 1 (rezultatul ultimei operaii a fost zero), se sare la eticheta specificat. Instruciunea LOOPNZ/LOOPNE (Loop While Not Zero/Equal - Cicleaz ct timp nu este zero/egal) LOOPNZ eticheta LOOPNE eticheta Se decrementeaz CX i, dac acesta este diferit de zero i ZF este 0 (rezultatul ultimei operaii a fost zero), se sare la eticheta specificat.

Aplicaii
1. Rulai pas cu pas urmtorul program:
.model small .stack 512 .data tab_proc dw proc_1 dw proc_2 dw proc_3 tab_procf dd procf_1 dd procf_2 dd procf_3 intra dw etich1 dw etich2 dw etich3 inter dd etif1 dd etif2 .code proc_1 proc push dx pop dx ret proc_1 endp proc_2 proc push dx pop dx ret proc_2 endp proc_3 proc push dx pop dx ret proc_3 endp procf_1 proc far push dx pop dx ret procf_1 endp procf_2 proc far push dx pop dx

18

ret procf_2 endp procf_3 proc far push dx pop dx ret procf_3 endp start: mov ax, @data mov ds, ax mov si, 0 jmp inter[si] etif2 label far jmp intra proced: lea bx, proc_1 call bx call tab_proc mov si, 2 call tab_proc[si] lea bx, tab_proc call word ptr [bx] mov si, 4 call word ptr [bx][si] call tab_procf mov si, 4 call tab_procf[si] lea bx, tab_procf call dword ptr [bx] mov si, 4 call dword ptr [bx][si] jmp sfarsit etich1: mov si, 2 jmp intra[si] etich3 label near jmp proced etich2 label near lea bx, intra jmp word ptr [bx+4] etif1 label far lea bx, inter mov si, 4 jmp dword ptr [bx][si] sfarsit:mov ah, 4ch int 21h end start

2. 3. 4.

5.

S se scrie un program care s afieze rezultatul obinut n urma conversiei unui numr hexazecimal n zecimal. S se scrie un program care s calculeze factorialul unui numr i apoi s afieze rezultatul. Care este coninutul registrului AL dup executarea urmtoarei secvene de instruciuni: mov al, A mov bl, B cmp al, bl jne et1 et2: mov al, 1 jmp sfarsit et1: mov al, 0 jmp sfarsit Care este coninutul registrului AL dup executarea urmtoarei secvene de instruciuni: masca equ 01000000b mov al, 10110101b test al, masca jz et1 et2: mov al, 1 jmp sfarsit et1: mov al, 0 jmp sfarsit

19

Programare n limbaj de asamblare Lucrarea nr. 5.

Instruciuni pentru operaii cu iruri


Prin ir se nelege o secven de octei sau de cuvinte, aflate la adrese succesive de memorie. Setul de instrucini cuprinde operaii primitive (la nivel de octet sau cuvnt) i prefixe de repetare, care pot realiza repetarea operaiilor primitive de un numr fix de ori sau pn la ndeplinirea unei condiii de tip comparaie. Denumirea instruciunilor fr operanzi la nivel de octet se termin cu litera B, iar a celor la nivel de cuvnt cu litera W. Aceste instruciuni folosesc registrele DS:SI ca adres surs i ES:DI ca adres destinaie. Exist i variantele cu operanzi ale acestor instruciuni, i ele se folosesc n situaia n care se utilizeaz alt segment pentru irul surs, dect segmentul de date implicit (DS). Toate aceste instruciuni incrementeaz (dac DF este 0) sau decrementeaz (dac DF este 1) n mod automat adresele (regitrii SI, DI) cu 1 sau cu 2, dup cum operaia este la nivel de octet sau de cuvnt. Starea flagului DF poate fi modificat prin instruciunile CLD (Clear Direction) i STD (Set Direction), care terg, respectiv seteaz acest bistabil.

1. Operaii primitive
Instruciunile MOVSB, MOVSW (Move String - Copiaz ir) MOVSB MOVSW ES:DI DS:SI SI SI + delta DI DI + delta Instruciunile CMPSB, CMPSW (Compare String - Compar iruri) CMPSB CMPSW DS:SI - ES:DI SI SI + delta DI DI + delta Instruciunile LODSB, LODSW (Load String - ncarc ir) LODSB LODSW acumulator DS:SI SI SI + delta (acumulator este AX sau AL n funcie de tipul operaiei)

Instruciunile STOSB, STOSW (Store String - Depune ir) STOSB STOSW ES:DI acumulator DI DI + delta (acumulator este AX sau AL n funcie de tipul operaiei)

20

Instruciunile SCASB, SCASW (Scan String - Cutare n ir) SCASB SCASW acumulator - ES:DI DI DI + delta (acumulator este AX sau AL n funcie de tipul operaiei)

2. Prefixe de repetare
Prefixele de repetare permit execuia repetat a unei operaii primitive cu iruri de octei sau de cuvinte, funcie de un contor de operaii sau de un contor i o condiie logic. Aceste prefixe nu sunt instruciuni n sine, ci particip la formarea unor instruciuni compuse, alturi de operaiile primitive descrise mai sus. Prefixul de repetare REP (Repeat - Repet) REP op_primitiva Repet operaia primitiv i decrementeaz CX, ct timp coninutul registrului CX este diferit de zero. De obicei se folosete la primitivele de tip MOVS, LODS i STOS.

Prefixul de repetare REPE/REPZ (Repeat While Zero/Equal - Repet ct timp este zero/egal) REPE/REPZ op_primitiva Repet operaia primitiv i decrementeaz CX, ct timp coninutul registrului CX este diferit de zero i rezultatul operaiei primitive este 0. De obicei se folosete la primitivele de tip CMPS i SCAS.

Prefixul REPNE/REPNZ (Repeat While Not Zero/Equal - Repet ct timp nu este zero/egal) REPNE/REPNZ op_primitiva Repet operaia primitiv i decrementeaz CX, ct timp coninutul registrului CX este diferit de zero i rezultatul operaiei primitive este de asemenea diferit de 0. De obicei se folosete la primitivele de tip CMPS i SCAS.

Observaie: Numrul elementelor unui ir se poate calcula folosind contorul de locaii. n exemplul urmtor, expresia $-text reprezint numrul octeilor de la adresa text pn la adresa curent: text db 'A B C D E F G H J K L M N O P Q R' ltext equ $-text De asemenea, operatorul LENGTH ntoarce numrul de elemente, iar operatorul SIZE ntoarce dimensiunea n octei a unei variabile. Astfel pentru definiia: tab dw 100 dup(?) expresia length tab are valoarea 100. Pentru aceeai definiie, expresia size tab are valoarea 200.

3. Aplicaii
1. 2. 3. 4. 5. 6. S se scrie un program care copiaz un ir ntr-un alt ir. Cutarea unui anumit caracter ntr-un ir. Se va afia pe ecran poziia caracterului n ir. S se scrie un program care d indicele caracterului ncepnd de la care dou iruri difer. S se scrie un program care afieaz pe ecran numrul de apariii a unui ir ntr-un alt ir. S se scrie un program care adun dou iruri de cifre zecimale aflate n zona de date. Rezultatul este un ir care conine pe fiecare poziie suma cifrelor de pe poziiile corespunztoare din cele dou iruri. Precizai care este efectul urmtoarei secvene de instruciuni: mov al, D mov cx, 12 rep stosb 21

Programare n limbaj de asamblare Lucrarea nr. 6.

1. Forma complet de definire a segmentelor


Se utilizeaz o declaraie de forma: nume_seg SEGMENT [tip_aliniere][tip_combinare][clasa_seg] nume_seg ENDS Iniializarea unui registru de segment (DS, ES sau SS) cu un segment declarat trebuie facut de utilizator n mod explicit n cadrul programului, utiliznd pentru aceasta numele segmentului respectiv: mov ax, nume_seg mov ds, ax tip_aliniere - poate fi BYTE, WORD, PARA, PAGE (implicit este PARA), i arat c adresa de nceput a zonei de memorie rezervat segmentului este divizibil cu 1/2/16/256. tip_combinare - este o informaie pentru editorul de legturi care indic raportul dintre acest segment i segmente definite n alte module obiect. Acest parametru poate fi: PUBLIC - arat c acest segment va fi concatenat cu alte segmente cu acelai nume, din alte module obiect, rezultnd un singur modul cu acest nume; COMMON - precizeaz c acest segment i alte segmente cu acelai nume din alte module vor fi suprapuse, deci vor ncepe de la aceeai adres. Lungimea unui astfel de segment va fi lungimea celui mai mare segment dintre cele suprapuse; AT <expresie> - segmentul va fi ncrcat n memorie la adresa fizic absolut de memorie reprezentat de valoarea expresiei, care este o valoare de 16 bii; MEMORY - segmentul curent de acest tip va fi aezat n memorie n spaiul rmas disponibil dup aezarea celorlalte segmente; STACK - va concatena toate segmentele cu acelai nume, pentru a forma un segment unic; referirea acestui segment se va face prin SS:SP. Registrul SP va fi iniializat automat cu lungimea stivei. clasa_seg - este un nume cuprins ntre apostrofuri. Rolul este de a permite stabilirea modului n care se aeaz n memorie segmentele unui program. Dou segmente cu aceeai clas vor fi aezate n memorie la adrese succesive. Asocierea segmentelor cu registrele de segment se realizeaz cu pseudoinstruciunea ASSUME: ASSUME reg_seg : nume_seg Unde reg_seg poate fi unul dintre registrele CS, DS, ES sau SS, iar nume_seg este numele unui segment sau al unui grup de segmente, care va fi adresat de registrul respectiv. Definirea grupurilor de segmente se realizeaz cu directiva GROUP, care are urmtoarea form: nume_grup GROUP lista_nume_segmente unde nume_grup este numele grupului de segmente, ce va fi folosit pentru a determina adresa de segment utilizat pentru referirea n cadrul grupului de segmente, iar lista_nume_segmente poate conine nume de segmente sau expresii de forma: SEG nume_variabila SEG nume_eticheta ntr-o astfel de list nu poate s apar numele unui alt grup. Exemplu: data1 segment v1 db 5 data1 ends

22

data2 segment v2 dw 25 data2 ends data3 segment v3 dw 100 data3 ends dgrup group data1, data2 cod segment assume cs:cod, ds:dgrup, es:data3 start: mov ax, dgrup mov ds, ax mov ax, data3 mov es, ax ;referiri la date mov bx, v1 ;se utilizeaz DS pentru ca a fost asociat cu dgrup add v3, bx ;se utilizeaz ES pentru ca a fost asociat cu segmentul data3 cod ends end start

2. Forma simplificat de definire a segmentelor


Aceast modalitate de definire a segmentelor respect acelai format ca i la programele dezvoltate n limbaje de nivel nalt. .MODEL tip_model Prin aceast directiv se specific dimensiunea i modul de dispunere a segmentelor n memorie. Modelul de memorie poate fi: - tiny - toate segmentele (date, cod, stiv) formeaz un singur segment de cel mult 64KB. Apelurile de procedur i salturile sunt de tip NEAR i se folosesc adrese efective (offset) pentru accesarea datelor; - small - datele i stiva formeaz un segment i codul un alt segment. Fiecare din acestea va avea dimensiunea maxima de 64KB. Apelurile de procedur i salturile sunt de tip NEAR i se folosesc adrese efective (offset) pentru accesarea datelor; - medium - datele i stiva sunt grupate ntr-un singur segment (cel mult egal cu 64KB), dar codul poate fi n mai multe segmente, deci poate depi 64KB. Apelurile de procedur i salturile sunt implicit de tip FAR i se folosesc adrese efective (offset) pentru accesarea datelor; - compact - codul generat ocup cel mult 64KB, dar datele i stiva pot fi n mai multe segmente (pot depi 64KB). Apelurile de procedur i salturile sunt de tip NEAR i se folosesc adrese complete (segment i offset) pentru accesarea datelor aflate n alte segmente; - large - att datele ct i codul generat pot depi 64KB. Apelurile de procedur i salturile sunt implicit de tip FAR i se folosesc adrese complete (segment i offset) pentru accesarea datelor aflate n alte segmente; - huge - este asemntor modelului large, dar structurile de date pot depi 64KB. La modelele compact i large, o structur compact de date (de tip tablou) nu poate depi limitele unui segment fizic (64KB); la modelul huge, aceast restricie dispare. .STACK [dimensiune] Aceast directiv aloc o zon de memorie de dimensiune specificat pentru segmentul de stiv. Dac nu se specific parametrul dimensiune, aceasta va fi implicit de 1KB. .CODE [nume] Aceast directiv precede segmentul de cod. ncrcarea adresei acestui segment n registrul CS se face automat de ctre sistemul de operare, la ncrcarea segmentului pentru execuie. Opional se pot asocia nume (maxim 6 caractere) pentru segmentele de cod. .DATA Aceast directiv precede segmentul de date. Utilizatorul trebuie s iniializeze, n mod explicit, registrul de segment DS, cu adresa segmentului de date. Simbolul @data primete adresa segmentului de date dup linkeditare.

23

3. Definirea structurilor. Operaii specifice


Structurile reprezint colecii de date plasate succesiv n memorie, grupate sub un unic nume sintactic. Dimensiunea unei structuri este suma dimensiunilor cmpurilor componente. Forma general este: nume_structura STRUC nume_membru definitie_date nume_structura ENDS Tipul structurii se definete fr a se rezerva spaiu de memorie. Numele membrilor structurii trebuie s fie distincte, chiar dac aparin unor structuri distincte. Iat un exemplu de definiie a unei structuri: alfa struc a db b dw c dd alfa ends

? 1111H 1234

O structur definit este interpretat ca un tip nou de date, care poate apoi participa la definiii concrete de date, cu rezervare de spaiu de memorie. De exemplu, putem defini o structur de tipul alfa, cu numele x: x alfa <, , 777> n care alfa este tipul de date, x este numele variabilei, iar ntre paranteze unghiulare se trec valorile iniiale ale cmpurilor structurii x. Prezena virgulelor din lista de valori iniiale precizeaz c primii doi membrii sunt iniializai cu valorile implicite de la definiia tipului alfa , iar al treilea membru este iniializat cu valoarea 777. Astfel, definiia variabilei x este echivalent cu secvena de definiii: a db b dw c dd ? 1111H 777

Principalul avantaj al structurilor este accesul la membri ntr-o form asemntoare limbajelor de nivel nalt. De exemplu, pentru a ncrca n SI cmpul b al structurii x, putem scrie: mov si, x.b Putem acum defini un tablou de 5 structuri de tip alfa: tab alfa 5 dup (<, , 10>) n care primii 2 membri sunt iniializai cu valorile de la definiia tipului structurii, iar al treilea cu valoarea 10. Avnd n vedere c o dat de tip alfa ocup 7 octei: - tab[0].a se refer la cmpul a al primei structuri; - tab[7].c se refer la cmpul c al celei de-a doua structuri; - tab[14].a se refer la cmpul a al celei de-a treia structuri; - tab[21].b se refer la cmpul b al celei de-a patra structuri.

4. Definirea nregistrrilor. Operaii specifice


nregistrrile corespund de fapt unor structuri mpachetate din limbajele de nivel nalt. Concret, o nregistrare este o definiie de cmpuri de bii de lungime maxim 8 sau 16. Forma general este: nume_inregistrare RECORD nume_camp:valoare [= expresie], unde valoare reprezint numrul de bii pe care se memoreaz cmpul respectiv. Opional poate fi folosit o expresie a crei valoare s fie asociat cmpului respectiv, pe numrul de bii precizat. La fel ca la structuri, numele cmpurilor trebuie s fie distincte, chiar dac aparin unor nregistrri diferite. S considerm un exemplu: beta record x:7, y:4, z:5 24

prin care se definete un ablon de 16 bii, x pe primii 7 bii (mai semnificativi), y pe urmtorii 4 bii, i z pe ultimii 5 bii (mai puin semnificativi). La fel ca la structuri, putem acum defini variabile de tipul nregistrrii beta: val beta <5, 2, 7> n care valorile dintre parantezele unghiulare iniializeaz cele trei cmpuri de bii. Aceast definiie este echivalent cu definiia explicit: val dw 0000101001000111B Operatorul MASK primete un nume de cmp i furnizeaz o masc cu biii 1 pe poziia cmpului respectiv i 0 n rest. Astfel, expresia MASK y este echivalent cu constanta binar 0000000111100000B. Operatorul WIDTH primete un nume de nregistrare sau un nume de cmp i ntoarce numrul de bii ai nregistrrii sau ai cmpului respectiv. De exemplu, secvena: mov al, width beta mov bl, width y va ncrca n AL 16 i n BL valoarea 4.

5. Macroinstruciuni
Macroinstruciunile permit programatorului s defineasc simbolic secvene de program (instruciuni, definiii de date, directive, etc.), asociate cu un nume. Folosind numele macroinstruciunii n program, se va genera ntreaga secven de program. n esen, este vorba de un proces de substituie (expandare) n textul programului, care se petrece nainte de asamblarea programului. Spre deosebire de proceduri, macroinstruciunile sunt expandate la fiecare utilizare. Forma general a unei macroinstruciuni este: nume_macro MACRO [p1, p2, ,pn] ENDM Opional, macroinstruciunile pot avea parametri, n acest caz, p1, p2, , pn sunt identificatori care specific parametrii formali. Apelul unei macroinstruciuni const n scrierea n program a numelui macroinstruciunii. Dac macroinstruciunuea are parametri, apelul se face prin specificarea numelui, urmat de o list de parametri actuali: nume_macro x1, x2, , xn La expandarea macroinstruciunii, pe lng expandarea propriu-zis, se va nlocui fiecare parametru formal cu parametrul actual corespunztor.

6.
1.

Aplicaii
Se consider urmtoarea definiie de date: alfa struc a1 db ? a2 db 21H a3 dw 5176H alfa ends tab alfa 10 dup (<3H, ?, 2252H>) Care va fi coninutul registrului AL dup executarea urmtoarelor instruciuni? a) mov al, byte ptr tab[12].a2 b) mov al, byte ptr tab[11].a2 S se defineasc o macroinstruciune care realizeaz adunarea a dou valori pe 32 de bii. S se scrie i un exemplu de apelare al macroinstruciunii definite. 25

2.

Programare n limbaj de asamblare Lucrarea nr. 7.

1.

ntreruperi

Noiunea de ntrerupere presupune intreruperea programului n curs de execuie i transferul controlului la o rutin de tratare. Mecanismul prin care se face acest transfer este, n esen, de tip apel de procedur, ceea ce nseamn revenirea n programul ntrerupt, dup terminarea rutinei de tratare. Pe lng rutinele de tratare ale sistemului de operare, pot fi folosite i propriile rutine. ntreruperile software apar ca urmare a execuiei unor instruciuni, cum ar fi INT, INTO, DIV, IDIV. Intreruperile hardware externe sunt provocate de semnale electrice care se aplic pe intrrile de ntreruperi ale procesorului, iar cele interne apar ca urmare a unor condiii speciale de funcionare a procesorului (cum ar fi execuia pas cu pas a programelor). ntr-un sistem cu procesor 8086, pot exista maxim 256 de ntreruperi. Fiecare nivel de ntrerupere poate avea asociat o rutin de tratare (procedur de tip far). Adresele complete (4 octei) ale acestor rutine sunt memorate n tabela vectorilor de intrerupere, pornind de la adresa fizic 0 pn la 1KB. Intrarea n tabel se obine nmulind codul ntreruperii cu 4. Rutina de tratare a ntreruperii se termin obligatoriu cu instruciunea IRET.

2. Redirectarea ntreruperii de pe nivelul 0


mprirea unui numr foarte mare la un numr mic, poate duce la apariia ntreruperii pe nivelul 0. Pentru obinerea rezultatului corect, se redirecteaz ntreruperea de pe nivelul 0 spre o rutin care realizeaz mprirea n situaia n care mpritorul este diferit de 0. Implementai programul de mai jos, i rulai-l pas cu pas. .model small .stack 100 .data demp dd 44444444h imp dw 1111h cat dd ? rest dw ? .code ;procedura primeste deimpartitul in (DX, AX) si impartitorul in BX ;returneaza catul in (BX, AX) si restul in DX divc proc cmp jnz int push push push mov mov push push mov mov div sub bx, 0 divc1 0 es di cx di, 0 es, di es:[di] es:[di+2] word ptr es:[di], offset trat_0 es:[di+2],cs bx bx, bx ;daca eroare adevarata ;apel tratare impartire cu 0 ;salvare registre modificate de procedura

divc1:

;adresa pentru intrarea intrerupere nivel 0 ;salvare adresa oficiala

;incarcare vector intrerupere ; pentru noua rutina de tratare ;incercare executie instructiune de impartire ;nu a aparut eroare ;daca impartirea s-a executat corect se pune 0 ;in bx ca sa corespunda modului de transmitere al parametrilor stabilit 26

revenire: pop es:[di+2] pop es:[di] pop cx pop di pop es ret trat_0 proc far push bp mov bp, sp

;salvare bp

mov push mov sub

div pop push mov

div pop pop iret trat_0 endp divc endp start: mov mov mov mov mov call mov mov mov mov int end start

;schimba adresa de revenire din rutina trat_0, adresa care se gaseste in stiva ;a fost pusa in stiva la apelare rutinei de intrerupere (IP-ul) word ptr [bp+2], offset revenire ax ;salvare ax, Y0 ax, dx ;primul deimpartit Y1 dx, dx ;executie impartire Y1 la X ;rezulta (AX) = Q1, (DX) = R1 bx cx ;Y0 ax ;salvare Q1 ax, cx ;executie impartire (R1, AX) la X ;rezulta AX=Q0, DX=R0 bx bx ;Q1 bp

ax, @data ds, ax ax, word ptr demp dx, word ptr demp+2 bx, imp divc word ptr cat, ax word ptr cat+2, bx rest, dx ah, 4ch 21h

27

Programare n limbaj de asamblare Lucrarea nr. 8.

1.

Transferul parametrilor ctre proceduri

1.1. Tipuri de transfer (prin valoare sau prin referin) O prim chestiune care trebuie decis n proiectarea unei proceduri este tipul de transfer al parametrilor. Se pot utiliza dou tipuri de transfer: transfer prin valoare, care implic transmiterea coninutului unei variabile; se utilizeaz atunci cnd variabila care trebuie transmis nu este alocat n memorie, ci ntr-un registru; transfer prin referin, care implic transmiterea adresei de memorie a unei variabile; se utilizeaz atunci cnd trebuie transmise structuri de date de volum mare (tablouri, structuri, tablouri de structuri, etc.). Se mai folosete atunci cnd procedura trebuie s modifice o variabil parametru formal alocat n memorie. S considerm o procedur aduna, de tip near, care adun dou numere pe 4 octei, ntorcnd rezultatul n perechea de registre DX:AX: .data n1 dd 12345H n2 dd 54321H rez dd ? .code aduna proc near add ax, bx adc dx, cx ret aduna endp mov ax, word ptr n1 mov dx, word ptr n1+2 mov bx, word ptr n2 mov cx, word ptr n2+2 call near ptr aduna mov word ptr rez, ax mov word ptr rez+2, dx S considerm acum varianta transmiterii prin referin a parametrilor, n care se transmit ctre procedur adresele de tip near ale variabilelor n1 i n1. aduna proc near mov ax, [si] add ax, [di] mov dx, [si+2] adc dx, [di+2] ret aduna endp lea si, n1 lea di, n2 call near ptr aduna mov word ptr rez, ax mov word ptr rez+2, dx

28

1.2. Transfer prin registre Avantajul transferului prin registre const n faptul c, n procedur, parametrii actuali sunt disponibili imediat. Principalul dezavantaj al acestei metode const n numrul limitat de registre. Pentru conservarea registrelor se folosete urmtoarea secven de apel: salvare n stiv a registrelor implicate n transfer; ncrcare registre cu parametri actuali; apel de procedur; refacere registre din stiv.

1.3. Transfer prin zon de date n aceast variant, se pregtete anterior o zon de date i se transmite ctre procedur adresa acestei zone de date. n exemplul urmtor transferul parametrilor ctre procedura aduna se face printr-o zon de date: .data zona label dword n1 dd 12345H n2 dd 54321H rez dd ? .code aduna proc near mov ax, [bx] add ax, [bx+4] mov dx, [bx+2] adc dx, [bx+6] ret aduna endp lea bx, zona call near ptr aduna mov word ptr rez, ax mov word ptr rez+2, dx

1.4. Transfer prin stiv Transferul parametrilor prin stiv este cea mai utilizat modalitate de transfer. Avantajele acestei metode sunt uniformitatea i compatibilitatea cu limbajele de nivel nalt. Tehnica de acces standard la parametrii procedurii se bazeaz pe adresarea bazat prin registrul BP, care presupune registrul SS ca registru implicit de segment. Accesul se realizeaz prin urmtoarele operaii, efectuate la intrarea n procedur: se salveaz BP n stiv; se copiaz SP n BP; se salveaz n stiv registrele utilizate de procedur; se acceseaz parametrii prin adresare indirect cu BP. La ncheierea procedurii, se execut urmtoarele operaii: se refac registrele salvate; se reface BP; se revine n programul apelant prin RET. Calculul explicit al deplasamentelor parametrilor reprezint o surs potenial de greeli, de aceea se utilizeaz un ablon care conine imaginea stivei, de la registrul BP n jos. S considerm procedura aduna de tip near, care primete parametrii n1 i n2 prin stiv .data n1 dd 12345H n2 dd 54321H rez dd ?

29

sablon struc _bp _ip n2_low n2_high n1_low n1_high sablon ends .code

dw ? dw ? dw ? dw ? dw ? dw ?

aduna proc near push bp mov bp, sp mov ax, [bp].n1_low add ax, [bp].n2_low mov dx, [bp].n1_high adc dx, [bp].n2_high pop bp ret aduna endp push word ptr n1+2 push word ptr n1 push word ptr n2+2 push word ptr n2 call near ptr aduna add sp,8 mov word ptr rez, ax mov word ptr rez+2, dx n cazul n care procedura este de tip far, pentru adresa de revenire trebuie rezervate n ablon 4 octei (adres complet): sablon struc _bp _cs_ip n2_low n2_high n1_low n1_high sablon ends .code aduna proc far push bp mov bp, sp mov ax, [bp].n1_low add ax, [bp].n2_low mov dx, [bp].n1_high adc dx, [bp].n2_high pop bp ret aduna endp push word ptr n1+2 push word ptr n1 push word ptr n2+2 push word ptr n2 call far ptr aduna add sp,8 mov word ptr rez, ax mov word ptr rez+2, dx

dw ? dd ? dw ? dw ? dw ? dw ?

30

2. ntoarcerea datelor de ctre proceduri


Exist urmtoarele modaliti de a ntoarce datele de ctre proceduri: n lista de parametri apar adresele rezultatelor sau adresa zonei de date care conine cmpuri pentru rezultate; rezultatele se ntorc prin registre; rezultatele se ntorc n vrful stivei. Prima tehnic a fost deja descris la transmiterea parametrilor prin zon de date. Practic, n interiorul procedurii se depun explicit rezultatele la adresele coninute n parametrii formali respectivi. A doua tehnic, transferul rezultatelor prin registre, se folosete cel mai frecvent. De obicei se folosete registrul acumulator, eventual extins (AL, AX, respectiv DX:AX, dup cum rezultatul este pe 1, 2 sau 4 octei). A treia tehnic, transferul rezultatelor prin stiv, se folosete destul de rar, fiind total nestandard.

3.
1. 2. 3.

Aplicaii
S se scrie un program care determin numrul biilor 1 dintr-un numr pe 32 de bii citit de la tastatur (se vor folosi instruciunile SHL i ADC); S se scrie o procedur care realizeaz adunarea a dou valori citite de la tastatur. Numerele sunt formate din maxim 32 de cifre. S se scrie un program care convertete un numr din format BCD mpachetat n format BCD despachetat. Numrul este format din 10 cifre. Rezultatul va fi memorat n zona de date. Pentru conversie se va utiliza o procedur care primete ca parametri adresa numrului BCD mpachetat i adresa la care va memora numrul BCD despachetat. Cei doi parametri sunt transmii prin stiv.

Observaii: citirea unui caracter de la tastatur se realizeaz folosind funcia 01H a ntreruperii 21H. Se ncarc n registrul AH valoarea 01H, se apeleaz ntreruperea 21H, care va pune codul ASCII al caracterului citit n AL; afiarea unui caracter pe ecran se realizeaz folosind funcia 02H a ntreruperii 21H. Se ncarc n registrul AH valoarea 02H. Se ncarc n DL codul ASCII al caracterului care trebuie afiat i apoi se apeleaz ntreruperea 21H, care va afia caracterul pe ecran; afiarea unui ir de caractere pe ecran (irul se termin cu caracterul $, care are codul ASCII 24H) se realizeaz folosind funcia 09H a ntreruperii 21H. Se ncarc n registrul AH valoarea 09H. Se ncarc n DS adresa de segment a irului care trebuie afiat, i n DX adresa efectiv (offsetul). Se apeleaz ntreruperea 21H, care va afia irul pe ecran. pentru trecerea la linie nou se afieaz irul de caractere: nl db 13, 10, 24H unde 13, 10 reprezint codul ENTER-ului.

31

Programare n limbaj de asamblare Lucrarea nr. 9.

1. Proceduri recursive
Numim procedur recursiv o procedur care se autoapeleaz (direct sau indirect). Forma general a unei funcii recursive este urmtoarea: tip f(lista_parametri_formali){ if (!conditie_de_oprire){ ... ... f(lista_parametri_reali) ... } } Recursivitatea poate fi utilizat pentru a rezolva elegant multe probleme, dar procedurile recursive sunt adesea mai lente dect corespondentele lor nerecursive: la fiecare apel se depun n stiv valorile parametrilor (dac exist) i adresa de revenire (vezi lucrarea de laborator nr. 6) complexitatea algoritmilor recursivi este de obicei mai mare dect a celor iterativi.

Aplicaie Enun : S se realizeze o funcie recursiv ce calculeaz n! Rezolvare :

Plecm de la formula recursiv de calcul

1, n = 0 n!= cunoscut din liceu. n (n 1)!, n > 0

Rescriind formula ntr-o variant mai apropiat de implementare, avem:

1, n = 0 fact (n) = n * fact (n 1), n > 0


Pentru a nelege mai uor programul realizat n limbaj de asamblare, s urmrim pentru nceput programul C, care declar o funcie recursiv fact, citete de la tastatur o valoare, i folosete funcia pentru a returna factorialul acestei valori:

#include <stdio.h> long fact(int n){ if(n==0) return 1; return n*fact(n-1) } void main(){ int n; scanf("%d",&n); printf("%ld",fact(n)); }

//conditia de oprire //apel recursiv: n!=n(n-1)!

//citire n //afisare n!

32

Analiz: La orice funcie recursiv trebuie precizat o condiie de ieire. n problema factorialului, condiia de ieire este 0! care, prin definiie, este 1. Dac parametrul primit de fact este 0, atunci funcia returneaz 1, altfel returneaz rezultatul nmulirii dintre valoarea parametrului i factorialul apelat cu valoarea parametrului minus 1. Pentru fact(3) avem urmtoarea succesiune de operaii: (1) (2) (3) (4) (5) (6) (7) apeleaz recursiv fact(2); apeleaz recursiv fact(1); apeleaz recursiv fact(0); returneaz 1 revenire din fact(0), calculeaz 1*fact(0); returneaz 1 revenire din fact(1), calculeaz 2*fact(1); returneaz 2 revenire din fact(2), calculeaz 3*fact(2); returneaz 6 revenire din fact(3);

fact(3) { if(n == 0) return 1; return 3 * fact(3-1); } fact(2) { if(n == 0) return 1; return 2 * fact(2-1); } fact(1) { if(n == 0) return 1; return 1 * fact(1-1); } 1 fact(0) { if(n == 0) return 1; }

Implementarea programului n limbaj de asamblare este urmtoarea: .model small .stack sablon struc _bp dw ? _cs_ip dw ? _n dw ? sablon ends .data n dw 7 rez dd ? .code fact proc near push bp mov bp, sp pushf push bx mov bx, word ptr [bp]._n cmp bx, 0 jne rec mov ax, 1

;salvare bp ;initializare cu varful stivei ;salvare indicatori ;preluarea parametrului ;conditia de oprire ;0!=1 33

mov dx, 0 jmp stop rec:dec bx push bx call near ptr fact add sp, 2 mul word ptr [bp]._n stop:pop bx popf pop bp retn fact endp afis proc near push ax push bx push cx push dx mov dx, word ptr rez+2 mov ax, word ptr rez mov cx, 0 mov bx, 10 next:div bx push dx mov dx, 0 inc cx cmp ax, 0 jne next print:pop dx add dl, 30h mov ah, 02h int 21h loop print pop dx pop cx pop bx pop ax retn afis endp start: mov ax, @data mov ds, ax mov ax, n push ax call near ptr fact add sp, 2 mov word ptr rez+2, dx mov word ptr rez, ax call near ptr afis mov ah, 4ch int 21h end start

;termenul urmator ;transferul parametrului ;apel recursiv, cu rezultat in DX:AX

;refacerea registrului bx ;refacere indicatori

;salvarea registrelor

;preluare din rez ;initializarea contorului ;se obtine pe rand in dx fiecare cifra zecimala ;salvarea in stiva e necesara pentru afisarea in ordinea corecta

;preluare din stiva ;conversie la codul ASCII ;afisare ;refacerea registrelor

;initializare registru segment

;transferul parametrului prin stiva ;DX:AX<--rezultatul ;rezultatul se depune in rez ;afisarea rezultatului ;revenire DOS

Pentru preluarea parametrului din stiv, procedura fact folosete urmtoarea structur ablon: sablon struc _bp dw ? _cs_ip dw ? _n dw ? sablon ends

34

Deoarece n problema factorialului, condiia de ieire este 0! care, prin definiie, este 1, dup preluarea parametrului, valoarea acestuia se compar cu 0. n caz de egalitate, n DX:AX se depune valoarea 1 i se face salt la eticheta stop (procedura ntoarce valoarea 1). Dac valoarea parametrului nu este 0, se returneaz rezultatul nmulirii dintre valoarea parametrului i factorialul apelat cu valoarea parametrului minus 1. S urmrim din nou succesiunea de operaii pentru acelai exemplu (3!), apelm deci procedura fact cu valoarea 3 trimis ca parametru: (1) (2) (3) (4) (5) (6) (7) apeleaz recursiv procedura fact, valoarea parametrului este 2; apeleaz recursiv procedura fact, valoarea parametrului este 1; apeleaz recursiv procedura fact, valoarea parametrului este 0; returneaz 1 n DX:AX revenire din fact(0); returneaz 1 n DX:AX revenire din fact(1); returneaz 2 n DX:AX revenire din fact(2); returneaz 6 n DX:AX revenire din fact(3);

Procedura afis preia rezultatul din rez (rezultatul se depune n rez nainte de a apela procedura afis), convertete aceast valoare n zecimal i o afieaz.

2. Aplicaii
1. Modificai programul prezentat, nlocuind procedura nerecursiv afis cu o procedur recursiv S se realizeze funcii care rezolv recursiv urmtoarele probleme:

2. Calculai

1, n = 0 2n = n 1 2 2 , n > 0

0, n = 0 3. Calculai cel de-al n-lea numr Fibonacci fibo( n) = 1, n = 1 fibo(n 1) + fibo(n 2), n > 1
1, n = k k 4. Calculai C n = 1, k = 0 k 1 k C n 1 + C n 1 , in rest

35

Programare n limbaj de asamblare Lucrarea nr. 10. 1. Aplicaii mixte C-ASM

1.1. Transferul parametrilor compilatorul de Borland C realizeaz tra nsferul parametrilor spre funcii prin stiv (n ordinea dreapta-stnga), apelul unei funcii C din ASM presupune plasarea parametrilor n stiv i apoi apelarea funciei C; deoarece n C descrcarea stivei este fcut de modulul apelant, un program ASM trebuie s descarce stiva dup apelarea unei funcii C.

1.2. ntoarcerea rezultatelor Dup executarea unei funciiC, rezultatul se va ntoarce n funcie de dimensiunea zcestuia, n felul urmtor: 1 octet: n registrul AL (char); 2 octei: n registrul AX (int i short); 4 octei: n perechea de registre DX:AX (long i float); float (4 octei), double (8 octei), long double (10 octei): ntr-o zon special a bibliotecii de virgul mobil sau n vrful stivei coprocesorului matematic. O soluie pentru rezultatele de tip real ar fi ca funcia s ntoarc pointeri la aceste valori.

1.3. Numele simbolurilor externe n C numele simbolurilor externe (nume de variabile, nume de funcii) sunt generate implicit cu caracterul _ precednd numele simbolului. Cu alte cuvinte, parametrii din C, utilizai i n modulul scris n limbaj de asamblare, vor fi precedai de caracterul _. n modulul n care simbolurile sunt definite, ele se declar PUBLIC, iar n modulele n care ele sunt referite se declar EXTRN. n unul din module (C sau ASM), trebuie s existe funcia main, care n ASM se declar n felul urmtor: public _main _main proc . ret _main endp Urmtoarea aplicaie mixt calculeaz recursiv factorialul unui numr citit de la tastatur: Modulul C: #include <stdio.h> #include <conio.h> Modulul ASM: .model tiny extrn _clrscr:near, _scanf:near, _printf:near, _getch:near public _main .stack 1024 sablon struc _bp dw ? _ip dw ? _n dw ? sablon ends .data n dw ? MesRd db 'Introduceti un intreg: ',0 MesWr db 'Factorialul este %d...',0 scan db '%d',0 36

;_cs_ip dd ? - modificare I

.code Factorial proc near push bp mov bp,sp

;Factorial proc far - modificare I

;+ push ds - modificare II ;+ push es - modificare II push dx push bx mov bx,[bp]._n cmp bx,1 jne et1 mov ax,1 jmp et2 et1: dec bx push bx call near ptr Factorial add sp,2 mul [bp]._n et2: pop bx pop dx

; parametru salvat in stiva ; call far ptr Factorial - modificare I

pop bp retn Factorial endp _main proc near call near ptr _clrscr

; ax - contine rezultatul deci nu se restaureaza ;+ pop es - modificare II ;+ pop ds - modificare II ; ===> ax nu trebuie salvat in stiva la inceputul proc ;retf - modificare I ;_main proc far - modificare I ; call far ptr _clrscr - modificare I ;+ mov ax, seg MesRd - modificare II ;+ push ax - modificare II

lea ax, MesRd push ax call near ptr _printf add sp,2

; call far ptr _printf - modificare I ; add sp, 4 - modificare II ;+ mov ax, seg n - modificare II ;+ push ax - modificare II

lea ax, n push ax ;+ mov ax, seg scan - modificare II ;+ push ax - modificare II lea ax, scan push ax call near ptr _scanf add sp,4 mov ax,n push ax call near ptr Factorial add sp,2 push ax

; call far ptr _scanf - modificare I ; add sp, 8 - modificare II

; call far ptr Factorial - modificare I

;+ mov ax, seg MesWr - modificare II ;+ push ax - modificare II lea ax,MesWr push ax call near ptr _printf add sp,4 call near ptr _getch retn _main endp end

; call far ptr _printf - modificare I ; add sp, 6 - modificare II ; call far ptr _getch - modificare I ; retf - modificare I

37

Observaie: Modificrile I trebuie fcute n cazul utilizrii modelelor de memorie cu apel de procedur de tip far, iar modificrile II trebuie fcute atunci cnd se folosesc modele de memorie cu adrese fizice (complete). n cel de-al doilea caz, simbolul @data trebuie modificat cu simbolul DGROUP.

2.

Aplicaii

S se realizeze funcii care rezolv recursiv urmtoarele probleme:

0, n = 0 1. Calculai suma cifrelor unui numr sumac ( n) = n%10 + sumac ( n / 10), n > 0

a , b = 0 2. Calculai cmmdc( a, b ) = cmmdc(b, a %b), b > 0


3. Se d un ir ordonat cresctor. Realizai funcia ce implementeaz cutarea binar. 0, s > d

1, a[ m] = val , unde m = ( s + d ) / 2 cauta ( s , d , val ) = cauta ( s, m 1, val ), a[ m] > val cauta ( m + 1, d , val ), a[ m] < val a[0], i = 0 a[i ] + sumas (i 1), i > 0

4. Suma elementelor unui vector sumas (i ) =

1, s >= d 5. Verificarea dac un vector e palindrom pali ( s , d ) = 0, a[ s ]!= a[ d ] pali ( s + 1, d 1), in rest 1, n = 1 6. Descompunerea unui numr n factori primi desc ( n, d ) = scrie d , desc ( n / d , d ), daca d | n desc ( n, d + 1), in rest
7. 8. Conversia unui numr din baza 10 n baza 2. Calculul coeficientului de grad n al polinomului Cebev de speta I. 1, n = 0 Tn ( x) = x, n =1 2T n 2 ( x) Tn 1 ( x)

n + 1, m = 0 9. Calculai valoarea functiei Ackermann A(m, n) A(m 1,1), n = 0 A(m 1, A(m, n 1)), in rest 10. Cautarea minimului i maximului intr-un sir de n valori.
11. Determinarea numrului de apariii a unei valori ntr-un ir.

38

Bibliografie
[1] [2] [3] [4] G. Musc, Programare n limbaj de asamblare, Editura Teora, 1998. V. Lungu, Procesoare INTEL - Programare n limbaj de asamblare, Editura Teora, 2001. R. Baciu, Programarea n limbaje de asamblare, Editura ALMA MATER, Sibiu, 2003. A. Florea, L. Vinan, Simularea i optimizarea arhitecturilor de calcul n aplicaii practice, Editura MATRIX ROM, Bucureti, 2003.

39

S-ar putea să vă placă și