Documente Academic
Documente Profesional
Documente Cultură
Asm
Asm
Aplicaii
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;
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.
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.:
; 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
; 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
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.
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
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
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
;pune n DL codul caracterului care trebuie afiat ;funcia DOS pentru afiarea caracterului din DL
10
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
1.
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.
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.
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
1.
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.
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.
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
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
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
23
? 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.
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.
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.
divc1:
;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
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
1.
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
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
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.
#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)); }
//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
;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
;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
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
;+ 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
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
;+ 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
0, n = 0 1. Calculai suma cifrelor unui numr sumac ( n) = n%10 + sumac ( n / 10), n > 0
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
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