1 / 33

Instrucţiuni de prelucrare la nivel de bit - instrucţiuni logice (NOT, AND, OR, XOR, TEST etc.);

Instrucţiuni de prelucrare la nivel de bit - instrucţiuni logice (NOT, AND, OR, XOR, TEST etc.); - instrucţiuni de deplasare (SHL, SAL, SHR, SAR etc.); - instrucţiuni de rotire (ROL, ROR, RCL, RCR); Instrucţiuni logice OF şi CF  0; AF - nedefinit;

osias
Télécharger la présentation

Instrucţiuni de prelucrare la nivel de bit - instrucţiuni logice (NOT, AND, OR, XOR, TEST etc.);

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Instrucţiuni de prelucrare la nivel de bit - instrucţiuni logice (NOT, AND, OR, XOR, TEST etc.); - instrucţiuni de deplasare (SHL, SAL, SHR, SAR etc.); - instrucţiuni de rotire (ROL, ROR, RCL, RCR); Instrucţiuni logice OF şi CF  0; AF - nedefinit; SF, ZF, PF - sunt poziţionaţi conform rezultatului instrucţiunii. NOT <dest> Nu afectează nici un indicator. AND <dest>, <sursa> (dest)  (dest) and (sursa) OR <dest>, <sursa> (dest)  (dest) or (sursa) XOR <dest>, <sursa> (dest)  (dest) xor (sursa) TEST <dest>, <sursa> Poziţionează indicatorii pentru operaţia (dest) and (sursa), fără a modifica nici un operand.

  2. Instrucţiuni de testare şi modificare de bit. Bitul testat este specificat prin deplasamentul său (al doilea operand, dată de 8 biţi sau reg_16/32) faţă de bitul cel mai puţin semnificativ al destinaţiei (reg/mem_6/32). Ceilalţi indicatori sunt nedefiniţi. BT <dest>, <poziţie> (Bit Test) (CF)  Bit (dest, poziţie) BTS <dest>, <poziţie> (Bit Test and Set) (CF)  Bit (dest, poziţie), Bit (dest, poziţie)  1 BTR <dest>, <poziţie> (Bit Test and Reset) (CF)  Bit (dest, poziţie), Bit (dest, poziţie)  0 BTC <dest>, <poziţie> (Bit Test and Complement) (CF)  Bit (dest, poziţie), Bit (dest, poziţie)  Not (Bit (dest, poziţie))

  3. Instrucţiuni de scanare pe bit. Aceste instrucţiuni permit scanarea biţilor din cel de-al doilea operand direct, începând cu bitul mai puţin semnificativ (forward) sau invers (reverse), pentru a determina primul bit egal cu 1. Dacă toţi biţii sunt zero ZF=1, altfel ZF=0, şi registrul destinaţie va reţine indexul primului bit 1 din operandul sursă (reg/mem de aceeaşi dimensiune cu reg. Dest.). Modif. ZF, iar toţi ceilalţi sunt nedefiniţi. - scanare directă: BSF <dest>, <sursa> (Bit Scan Forward) - scanare inversă: BSR <dest>, <sursa> (Bit Scan Reverse) • Instrucţiuni de setare condiţionată. Pun octetul pe zero sau unu, în funcţie de una din cele 16 condiţii definite de indicatori. Operandul destinaţie poate fi reg/mem. Aceste instrucţiuni sunt folosite pentru implementarea expresiilor booleene, din limbajele de nivel înalt.

  4. SETcond <dest> (SET byte on condition) if cond then (dest)  1 else (dest)  0 SETE / SETZ ZF = 1 SETNE / SETNZ ZF = 0 SETL / SETNGE SF <> OF, valori cu semn SETLE / SETNG SF <> OF sau ZF = 1, valori cu semn SETNL / SETGE SF = OF, valori cu semn SETNLE / SETG SF = OF şi ZF = 0, valori cu semn SETB / SETNAE / SETC CF = 1, valori fără semn SETBE / SETNA CF = 1 sau ZF = 1,fără semn SETNB / SETAE / SETNC CF = 0, valori fără semn SETNBE / SETA CF = 0 şi ZF = 0,fără semn SETO / SETNO OF = 1 / respectiv OF = 0 SETP / SETPE PF = 1, adică paritate pară

  5. SETNP / SETPO PF = 0, adică paritate impară SETS / SETNS SF = 1 / respectiv SF = 0 • Instrucţiuni de deplasare Deplasările pot fi aritmetice sau logice. Se poate deplasa operandul destinaţie cu până la 31 de biţi, corespunzător operandului contor, codificat în instrucţiune (sunt luaţi în considerare numai ultimii 5 biţi ai acestuia). OF = este nedefinit într-o deplasare pe mai mulţi biţi; = este poziţionat pt. deplasare de un bit; CF = ultimul bit deplasat în afara operandului destinaţie; AF = nedefinit; SF, ZF, PF = modificaţi conform rezultatului. SHL / SAL <dest>, <contor> (SHift logical / Arithmetic Left) Poziţiile eliberate devin zero; între cele două mnemonici nu există nici o deosebire. Bitul cel mai semnificativ se deplasează în CF.

  6. SHR <dest>, <contor> (SHift logical Right) SAR <dest>, <contor> (Shift Arithmetic Right) Bitul cel mai semnificativ îşi păstrează vechea valoare, dar este şi deplasat spre dreapta (extensie de semn), ceea ce înseamnă că nu poate să apară depăşire (schimbarea de semn a rezultatului) şi (OF)=0 la o deplasare de 1 bit. Trebuie menţionat că SAR nu furnizează acelaşi rezultat ca instrucţiunea IDIV, pentru aceeaşi operanzi, dacă deîmpărţitul este negativ, şi sunt deplasaţi (SAR) în afara operandului biţi egali cu 1. De exemplu -5 deplasat la dreapta (SAR), cu un bit va furniza -3, în timp ce împărţirea întreagă (IDIV) va furniza valoarea -2: (-5) = (11111011)  (11111101) = (-3) Diferenţa dintre cele două instrucţiuni este că IDIV trunchiază toate câturile către zero, în timp ce SAR trunchiază numerele pozitive către zero, iar pe cele negative către infinit negativ.

  7. La 386/486 pot fi realizate instrucţiuni de deplasare dublă, pe cuvânt sau dublu cuvânt. Operandul destinaţie poate fi reg/ mem, iar sursa reg. general. Rezultatul înlocuieşte operandul destinaţie, iar contorul numărului de biţi deplasaţi este specificat de registrul CL, sau ca o valoare imediată de 8 biţi. Indicatorii sunt poziţionaţi la fel ca la deplasările anterioare. SHLD <dest>, <sursa>, <contor> (SHift Left Double) CF  . . . . . . Dest   . . . . . . Sursa SHRD <dest>, <sursa>, <contor> (SHift Right Double) Dest  . . .  CF  Sursă  . . . 

  8. Registrul sursă nu se modifică. Instrucţiunea este utilă atunci când se împachetează date din mai multe surse diferite. • Instrucţiuni de rotire În cazul rotaţiilor, biţii deplasaţi în afara operandului nu sunt pierduţi, ca în cazul deplasărilor, ci sunt rotiţi (circulaţi) înapoi către celălalt capăt al operandului. Începând de la procesoarele 286 contorul, chiar dacă este diferit de 1, el poate fi specificat în instrucţiune, ca dată imediată. Rotaţiile modifică numai CF şi OF: CF = ultimul bit rotit în afara operandului; OF = nedefinit pentru rotaţii multibit; = 1 sau 0, pentru rotaţie doar de 1 bit, după cum s-a modificat sau nu bitul de semn al operandului.

  9. ROL <dest>, <contor> (ROtate Left) CF  Bn  . . . . . . B0  Bn ROR <dest>, <contor> (ROtate Right) B0  CF Bn  . . . . . .  B0  Bn RCL <dest>, <contor> (Rotate through Carry Left) B0  CF  Bn  . . . . . .  B0  CF RCR <dest>, <contor> (ROtate through Carry Right) B0  CF  Bn  . . . . . .  B0  CF 1) Înmulţirea cu 20 a uni număr din registrul AX: ; 20 = 16 + 4 = 24 + 22 ; deci 2 deplasări la stânga, se salvează rezultatul, mov cl, 2 ; care reprezintă * 4, şi încă două deplasări shl ax, cl mov bx, ax ; se salvează *4 în (BX)

  10. mov cl, 2 ; contorul pentru încă două deplasări (*16) shl ax, cl ; care realizează * 16, şi se adună cele două add ax, bx ; rezultate parţiale 2) Împărţirea la 1024 a valorii din registrul AX: mov cl, 2 ; 1024 = 210 = 28 * 22 sar ah, cl ; după 8 deplasări la dreapta AL se pierde xchg ah, al ; (sau mov ah, al), e suficient să deplasăm AH la cbw ; dreapta cu 2, şi apoi să-i facem extensia de semn 3) Împărţirea unui număr de 32 biţi (64) la o putere a lui 2, de exemplu la 64 = 26: mem_32 dd 50000; . . . . . ; trebuie deplasat numărul la dr. cu 6 biţi mov cx, 6 ; contorul numărului de deplasări iar: sar word ptr mem_32[2], 1 ; bitul 17  (CF) rcr word ptr mem_32[0], 1 ; (CF)  bitul 16 loop iar

  11. 4) Determinarea numărului de biţi egali cu 1 dintr-o variabilă. .model small .stack 100h .data lung_var equ 8 variabila dw lung_var dup (0acfh) nr_unitati db ? .code assume cs: @code, ds: @data start: mov ax, @data mov ds, ax mov si, 0 ; indexul curent al cuvintelor din variabila mov dl, lung_var ; contor număr de cuvinte mov bl, 0 ; contor număr de unităţi găsite bucla2: mov cx, 16 ; contorul de biţi pentru un cuvânt

  12. mov ax, variabila[si] ; se citeşte cuvântul curent bucla1: rcl ax, 1 ; o rotaţie pentru a deplasa un bit adc bl, 0 ; se contorizează numărul de unităţi loop bucla1 ; pentru un cuvânt add si, type variabila ; se actualizează indexul dec dl ; se testează dacă mai sunt cuvinte jnz bucla2 ; dacă da se reia citirea cuvintelor mov nr_unitati, bl ; dacă nu se depune rezultatul mov ax, 4C00h ; revenire DOS int 21h end 4a). Aceeaşi problemă poate fi rezolvată utilizând instrucţiunile BSF şi BTR, astfel:

  13. mov cx, lung_var ; contor dimensiune variabilă mov bl, 0 ; contor unităţi mov si, 0 ; index cuvinte bucla: mov ax, variabila[si] scanare: bsf dx, ax ; determină primul bit 1 (indexul în DX) jz gata_cuv ; dacă ZF=0, toţi biţii sunt 0 btr ax, dx ; transferă 1 din AX, din poziţia DX în CF, adc bl, 0 ; iar bitul =0, sau inc bl, numără unităţile jmp scanare ; se reia scanarea cuvântului curent gata_cuv: add si, 2 ; indexul cuvântului următor loop bucla ; decrementare contor număr de cuv. variabilă ; dacă nu s-a terminat variabila ia cuv. următor

  14. 5) Tipărirea conţinutului registrului DX, în format octal: tip_car proc far ; procedura tipăreşte caracterul al cărui cod ASCII ; îl primeşte în registrul AL push dx ; se salvează registrul de lucru DX mov dl, al ; se apelează funcţia 2 din DOS care mov ah, 2 ; tipăreşte caracterul al cărui cod int 21h ; ASCII se transmite în registrul DL pop dx ; se reface registrul salvat ret tip_car endp tip_octal proc far ; tipăreşte în octal valoarea, fără semn transmisă în DX push cx ; se salvează registrele de lucru push ax

  15. ; prima cifră de tipărit este doar de 1 bit rol dx, 1 ; care este rotit pe ultimul bit mov al, dl ; şi dusă în registrul AL and al, 1 ; se şterg ceilalţi biţi add al, 30h ; este convertită la codul ASCII call tip_car ; şi se tipăreşte ; următoarele 5 cifre sunt de câte 3 biţi mov cx, 5 ; contor număr de cifre de tipărit octal1: push cx ; se salvează contorul în stivă mov cl, 3 ; contor număr de rotiri la stânga rol dx, cl ; cifra este rotită pe ultimii 3 biţi mov al, dl ; şi adusă în AL and al, 7 ; sunt şterşi ceilalţi biţi add al, 30h ; şi convertită la codul ASCII call tip_car ; tipărirea cifrei

  16. pop cx ; se citeşte valoarea contorului de cifre loop octal1 pop ax ; se refac registrele salvate în stivă pop cx ret tip_octal endp

  17. Instrucţiuni de operare pe şiruri Există cinci operaţii de bază ce operează pe şiruride lungime de până la un segment (64K la 286, respectiv 4G la 386/486), şi permit: mutare, comparare de şiruri, scanarea unui şir pentru o valoare şi transfer la/de la acumulator. Aceste operaţii de bază pot fi precedate de un prefix special de un octet care are ca efect repetarea instrucţiunii prin hardware. Repetiţia se poate termina printr-o varietate de condiţii, iar o operaţie repetată poate fi întreruptă sau suspendată. O instrucţiune pe şir poate avea un operand sursă, un operand destinaţie sau pe amândoi. Şirul sursă este în (DS) sau într-un alt segment, dacă este prefixat peste această presupunere. Şirul destinaţie se află, întotdeauna, în segmentul dat de registrul (ES). SI este ca offset pentru elementului curent al şirului sursă, iar DI este offset pentru şirul destinaţie. Instrucţiunile pe şir actualizează automat SI şi/sau DI. DF determină dacă registrele index sunt auto-incrementate-decrementate (DF=0-1), iar pas de actualizare depinde de tipul şirurilor: 1 - octet, 2 - cuvânt, 4 - dublu cuvânt.

  18. Dacă este prezent un prefix de repetare reg. CX este decrementat la fiecare repetiţie a instrucţiunii pe şir; repetarea va lua sfârşit când CX=0, sau pentru unele prefixe şi în funcţie de ZF. Sunt cinci mnemonici pentru două forme de prefix octet, care controlează repetarea unei instrucţiuni pe şir(uri). Prefixele de repetare nu afectează indicatorii. REP / REPE / REPZ / REPNE / REPNZ REP - REPeat - este utilizat împreună cu MOVS- STOS, "repetă cât timp nu este sfârşitul şirului, adică (CX<>0)"; REPE / REPZ - REPeat while Equal / Zero - care operează la fel şi au fizic acelaşi prefix octet ca REP. Sunt utilizate pentru CMPS şi SCAS, şi necesită, în plus faţă de condiţia anterioară, ca ZF să fie setat înainte de efectuarea următoarei repetiţii; REPNE / REPNZ - REPeat while Not Equal / Zero - este asemănător cu cele anterioare, cu deosebirea că ZF trebuie pus pe 0, sau repetiţia se termină.

  19. MOVS <sir_dest>, <sir_sursa> (MOVe data from String to string) MOVSB / MOVSW / MOVSD Se transferă un element (octet/cuvânt/dublu cuvânt) de la sursă (SI) la destinaţie (DI), şi actualizează SI/DI Utilizată împreună cu prefixul REP realizează un transfer de bloc memorie-memorie. CMPS <sir_dest>, <sir_sursa> (COMPare String operands) CMPSB / CMPSW / CMPSD Această instrucţiune scade operandul destinaţie (referit de DI) din cel sursă (referit de SI), modifică indicatorii de stare, dar nu alterează nici unul dintre operanzi, după care actualizează SI/DI. Trebuie reţinut că spre deosebire de instr. CMP care scade sursa din destinaţie, CMPS realizează scăderea invers: sursă - destinaţie. Dacă CMPS are prefixul REPE sau REPZ operaţia este interpretată "compară cât timp nu este sfârşit şirul (CX<>0) şi şirurile sunt egale (ZF=1)"; determina prima pereche de elemente diferite.

  20. Dacă CMPS este precedată de REPNE/REPNZ "compară cât timp nu este sfârşit de şir (CX<>0), şi elementele şirurilor nu sunt egale (ZF=0)"; determina prima pereche de elemente egale. SCAS <sir_dest> (SCAn String data) SCASB / SCASW / SCASD Instrucţiunea scade elem. şir dest. (octet/ cuvânt/ dublu cuvânt) adresat de DI, din AL, AX sau EAX, şi actualizează indicatorii, dar fără a modifica şirul destinaţie sau acumulatorul. Dacă SCAS este prefixată de REPE/REPZ "scanează cât timp nu este sfârşitul şirului (CX<>0) şi valoarea scanată este egală cu elementele şirului (ZF=1)"; determina abaterea faţă de o valoare. Dacă SCAS este prefixată de REPNE/REPNZ "scanează cât timp nu este sfârşitul şirului (CX<>0) şi valoarea scanată este diferită de elementele şirului (ZF=0)"; localizează o valoare într-un şir.

  21. LODS <sir_sursa> (LOaD String operand) LODSB / LODSW / LODSD Transferă elementul şirului sursă adresat de SI, în AL, AX sau EAX, şi actualizează SI. Instrucţiunea se utilizează în bucle soft. STOS <sir_dest> (STOre String data) STOSB / STOSW / STOSD Transferă un element din acumulator (AL, AX, EAX) în şirul destinaţie, şi actualizează DI, pentru a referi următorul element. Instrucţiunea poate fi precedată de prefixul REP, şi astfel se poate iniţializa un şir cu o constantă.

  22. 1) Copierea unui şir de octeţi dintr-o zonă de memorie într-alta. date_sir segment word public 'data' sir1 db 1000 dup (7,0f0h) ; şirul sursă lung1 equ $ - sir ; lungimea şirului sursă sir2 db 1000 dup (2 dup (?)) ; rezervare pt. şir dest. ptr_sir1 dd sir1 ; pointer sir1 ptr_sir2 dd sir2 ; pointer sir2 date_sir ends cod segment word public 'code' assume cs:cod, ds:date_sir, es:date_sir start: mov ax, date_sir ; iniţializare registru segment DS mov ds, ax ; şi apoi adresele celor două şiruri mov es, ax ; sau: les di,ptr_sir2 lea di, sir2 ; lds si,ptr_sir1 lea si, sir1

  23. mov cx, lung1 ; contorul transferului = lungimea sursei cld ; direcţia de parcurgere a şirului (df=0) repeta: lodsb stosb ; sau: movs sir2,sir1 , sau movsb loop repeta ; sau: rep movsb mov ax, 4c00h ; revenire DOS int 21h cod ends end start

  24. 2) Copierea informaţiei dintr-un buffer din memorie în memoria ecran. În modul text pentru fiecare caracter de pe ecran se rezervă doi octeţi: unul reprezintă atributele de afişare (afişare continuă / intermitentă - 1 bit, culoare fond - 3 biţi, culoare caracter - 4 biţi), iar cel de-al doilea este codul ASCII al caracterului afişat. .model small .data mem_ecran dd 0B8000000h ; adresa memoriei ecran dimensiune equ 2000 buffer dw dimensiune dup (3a33h); se va afişa acelaşi caracter ptr_buf dd buffer .code start: mov ax, @data ; iniţializare DS mov ds, ax mov ah, 0 ; selecţie mod de lucru mov al, 0 ; alfanumeric 40*25 alb/negru, pt. 80*25 al=2

  25. int 10h les di, mem_ecran lds si, ptr_buf mov cx, dimensiune cld ; direcţia de parcurgere rep movsw ; transfer buffer în mem_ecran mov ax, 4c00h ; revenire DOS int 21h .stack 10h end start

  26. 3) Determinarea poziţiei unui anumit caracter (sau a unui şir de caractere) într-un fişier sursă de pe disc. .model small .stack 10h .data car equ 'A’ ; caracterul de identificat (sau şirul) lung equ 2048 ; dimensiunea maximă a fişierului-4 sectoare buffer db lung dup (?); spaţiu de mem. pentru fişier nume_fis db 'fisier.asm', 0 ; nume fişi.- ASCIIZ, adică după ; numele poate fi precedat şi de calea de acces pozitie dw ? ; poziţia caracterului în fişier nr_logic dw ? ; numărul logic atribuit fişierului contor dw ? ; numărul efectiv de caractere citite mes_lipsa db 'nu exista fisier cu acest nume$' mes_err_cit db 'eroare de citire de pe disc$' mes_car_lipsa db 'caracterul cautat nu este in fisier$'

  27. .code start: mov ax, @data ; iniţializare DS mov ds, ax mov ah, 3dh ; apel DOS pentru deschidere de fişier mov al, 0 ; în modul "citeşte" (1-scrie,2-citire/scriere) lea dx, nume_fis ; adresa numelui fişierului int 21h ; apel funcţie 'deschide fişier' jc lipsa_fis mov nr_logic, ax ; se depune numărul sectorului mov bx, ax ; şi în BX, pentru funcţia de citire mov cx, lung ; contor număr maxim de caractere citite lea dx, buffer ; adresa unde se vor depune caracterele mov ah, 3fh ; funcţia de citire din fişier int 21h jc err_cit ; dacă a apărut eroare al citire

  28. mov contor, ax ; la 'contor' se depune numărul de car. mov cx, ax ; contor de căutare 'car' push ds ; se încarcă în ES adresa de segment pop es ; a 'buffer'-ului lea di, buffer ; şi în registrul (DI) offsetul acestuia mov al, car ; caracterul de căutat cld ; stabilire direcţie de parcurgere, (DF)=0 repne scasb ; continuă scanarea până-l găseşte je gasit ; dacă nu s-a găsit nu se face saltul lea dx, mes_car_lipsa ; şi se tipăreşte mesajul mov ah, 9 ; mesajul: 'caracterul cautat nu este in fisier' int 21h jmp gata gasit: dec di ; poziţia caracterului căutat, (DI)-1 mov pozitie, di ; deoarece (DI) a fost actualizat după

  29. jmp gata ; scanare lipsa_fis: lea dx, mes_lipsa ; nu s-a găsit fişierul cu mov ah, 9 ; numele specificat int 21h jmp gata err_cit: lea dx, mes_err_cit ; eroare la citirea fişierului mov ah, 9 int 21h gata: mov ah, 3eh ; închiderea fişierului deschis mov bx, nr_logic int 21h mov ax, 4c00h ; revenire DOS int 21h end start

  30. Determinarea poziţiei unui şir de caractere într-un fişier: sir_car db 'asamblare' lung_sir dw $-sir_car ptr_sir dd sir_car ptr_buf dd buffer pozitie dw ? ; poziţia şirului de caractere . . . . . . . . . . . . . . . . . . . les di, ptr_buf lds si, ptr_sir mov cx, contor ; dimensiune buffer sub cx, lung_sir ; căutarea se va face începând de la 0 inc cx ; până la (contor) - (lung_sir) cld ; direcţia de parcurgere (DF=0) reia: push si ; se salvează adresa şirului căutat push di ; se salvează adresa şirului în care se căută

  31. push cx; se salvează contorul numărului maxim de căutări mov cx, lung_sir ; contorul de comparaţii repe cmps buffer, sir_car ; se compară cât timp sunt egale pop cx ; reface resurse salvate în stivă: contorul pop di ; şi adrese şiruri: destinaţie - şirul în care se pop si ; caută, sursă – (sub)şirul care se caută je gasit ; salt dacă s-a găsit sir_car în buffer inc di ; căutarea se va relua de la următorul caracter loop reia ; din buffer, dacă (contor) <> 0 ; -> şirul de caractere nu este în fişierul dat (respectiv în buffer) jmp nu_gasit gasit: mov pozitie, di ; valoarea salvată pentru (DI) . . . . . . . . . . . . . . . . . . . nu_gasit: ; tipărire mesaj: ‘Nu s-a gasit sirul de caractere’

More Related