User Tools

Site Tools


laboratoare:laborator-05

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revision Previous revision
Next revision
Previous revision
Last revision Both sides next revision
laboratoare:laborator-05 [2015/11/11 07:59]
razvan.deaconescu [Suma elementelor într-un vector]
laboratoare:laborator-05 [2015/11/11 15:12]
razvan.deaconescu [[1.5p] 5. Suma pătratelor primelor N numere naturale]
Line 92: Line 92:
 <​code>​ <​code>​
  
-mov BYTE PTR [ebx], 2  ; Move 2 into the single byte at memory location EBX +mov byte [ebx], 2  ; Move 2 into the single byte at memory location EBX 
-mov WORD PTR [ebx], 2  ; Move the 16-bit integer representation of 2 into the 2 bytes starting at+mov word [ebx], 2  ; Move the 16-bit integer representation of 2 into the 2 bytes starting at
                        ; address EBX                        ; address EBX
-mov DWORD PTR [ebx], 2 ; Move the 32-bit ​+mov dword [ebx], 2 ; Move the 32-bit ​
  
 </​code>​ </​code>​
Line 105: Line 105:
 Descărcați arhiva, decomprimați-o și accesați directorul aferent. Descărcați arhiva, decomprimați-o și accesați directorul aferent.
  
-==== Tutorial: Înmulțire două numere reprezentate pe un octet ====+==== [0.5p] 1. Tutorial: Înmulțire două numere reprezentate pe un octet ====
  
 Parcurgeți rulați și testați codul  din fișierul ''​multiply.asm''​. În cadrul programului înmulțim două numere definite ca octeți. Pentru a le aputea accesa folosimo construcție de tipul ''​byte [register]''​. Parcurgeți rulați și testați codul  din fișierul ''​multiply.asm''​. În cadrul programului înmulțim două numere definite ca octeți. Pentru a le aputea accesa folosimo construcție de tipul ''​byte [register]''​.
  
 Atunci cănd facem înmulțire procesul este următorul, așa cum este descris și [[https://​en.wikibooks.org/​wiki/​X86_Assembly/​Arithmetic|aici]]:​ Atunci cănd facem înmulțire procesul este următorul, așa cum este descris și [[https://​en.wikibooks.org/​wiki/​X86_Assembly/​Arithmetic|aici]]:​
-  - Plasăm ​înmulțitorul ​în registrul ​''​AL''​ (pentru ​operații pe un byte), registrul ''​AX'' ​(pentru ​operații ​pentru ​cuvânt ​16 biți, 2 octeți) și registrul ''​EAX''​' (pentru ​operații pe dublu cuvânt ​32 de biți, 4 octeți). +  - Plasăm ​deînmulțitul în registrul ​de deînmulțit,​ adică: 
-  - Deînmulțitul este transmis ca argument mnemonicii ''​mul''​.+    - dacă facem operații pe un byte (8 biți, un octet), plasăm deînmulțitul în registrul ''​AL''​
 +    - dacă facem operații ​pe un cuvânt ​(16 biți, 2 octeți, plasăm deînmulțitul în registrul ''​AX''​
 +    - dacă facem operații pe un dublu cuvânt ​(32 de biți, 4 octeți), plasăm deînmulțitul în registrul ''​EAX''​
 +  - Înmulțitorul ​este transmis ca argument mnemonicii ''​mul''​. Înmulțitorul trebuie să aibă aceeași dimensiune ca deînmulțitul.
   - Rezultatul este plasat în două registre (partea //high// și partea //low//).   - Rezultatul este plasat în două registre (partea //high// și partea //low//).
  
 Testați programul. Încercați alte valori pentru ''​num1''​ și ''​num2''​. Testați programul. Încercați alte valori pentru ''​num1''​ și ''​num2''​.
  
-==== Înmulțire două numere ====+==== [2p] 2. Înmulțire două numere ====
  
 Actualizați zona marcată cu ''​TODO''​ în fișierul ''​multiply.asm''​ pentru a permite înmulțirea și a numelor de tip ''​word''​ și ''​dword'',​ adică ''​num1_dw''​ cu ''​num2_dw'',​ respectiv ''​num1_dd''​ și ''​num2_dd''​. Actualizați zona marcată cu ''​TODO''​ în fișierul ''​multiply.asm''​ pentru a permite înmulțirea și a numelor de tip ''​word''​ și ''​dword'',​ adică ''​num1_dw''​ cu ''​num2_dw'',​ respectiv ''​num1_dd''​ și ''​num2_dd''​.
Line 122: Line 125:
 <note tip> <note tip>
 Pentru înmulțirea numerelor de tip ''​word''​ (pe 16 biți), componentele sunt dispuse astfel: Pentru înmulțirea numerelor de tip ''​word''​ (pe 16 biți), componentele sunt dispuse astfel:
-  * În registrul ''​AX''​ se plasează ​înmulțitorul+  * În registrul ''​AX''​ se plasează ​deînmulțitul
-  * Argumentul instrucțiunii ''​mov''​ (posibil un alt registru) este pe 16 biți (fie valoare fie un registru precum ''​BX'',​ ''​CX'',​ ''​DX''​).+  * Argumentul instrucțiunii, înmulțitorul, ​''​mul''​ (posibil un alt registru) este pe 16 biți (fie valoare fie un registru precum ''​BX'',​ ''​CX'',​ ''​DX''​).
   * Rezultatul înmulțirii este dispus în perechea ''​DX:​AX'',​ adică partea "​high"​ a rezultatului în registrul ''​DX'',​ iar partea "​low"​ a rezultatului în registrul ''​AX''​.   * Rezultatul înmulțirii este dispus în perechea ''​DX:​AX'',​ adică partea "​high"​ a rezultatului în registrul ''​DX'',​ iar partea "​low"​ a rezultatului în registrul ''​AX''​.
 +
 +Pentru înmulțirea numerelor de tip ''​dword''​ (pe 32 biți), componentele sunt dispuse astfel:
 +  * În registrul ''​EAX''​ se plasează deînmulțitul.
 +  * Argumentul instrucțiunii,​ înmulțitorul,​ ''​mul''​ (posibil un alt registru) este pe 32 biți (fie valoare fie un registru precum ''​EBX'',​ ''​ECX'',​ ''​EDX''​).
 +  * Rezultatul înmulțirii este dispus în perechea ''​EDX:​EAX'',​ adică partea "​high"​ a rezultatului în registrul ''​EDX'',​ iar partea "​low"​ a rezultatului în registrul ''​EAX''​.
  
 </​note>​ </​note>​
  
-==== Ridicare număr la puterea a treia ====+<​note>​ 
 +La afișarea rezultatului folosiți două instrucțiunii ''​PRINT_UDEC''​ pentru a afișa cele două registre care conțin rezultatul:​ 
 +  * Registrele ''​DX''​ și ''​AX''​ pentru înmulțirea numerelor de tip ''​word''​. 
 +  * Registrele ''​EDX''​ și ''​EAX''​ pentru înmulțirea numerelor de tip ''​dword''​. 
 + 
 +</​note>​ 
 +==== [1p] 3. Ridicare număr la puterea a treia ====
  
 Realizați un program în limbajul de asamblare care ridică un număr la puterea a treia (adică ''​num * num * num''​). Realizați un program în limbajul de asamblare care ridică un număr la puterea a treia (adică ''​num * num * num''​).
Line 138: Line 152:
 Nu definiți un număr foarte mare, pentru a putea fi vizualizat rezultatul înmulțirii în registrul ''​eax''​. Nu definiți un număr foarte mare, pentru a putea fi vizualizat rezultatul înmulțirii în registrul ''​eax''​.
  
-==== Tutorial: Suma elementelor dintr-un vector reprezentate pe un octet ====+==== [0.5] 4. Tutorial: Suma primelor N numere naturale ==== 
 + 
 +În programul ''​sum_n.asm''​ din [[http://​elf.cs.pub.ro/​asm/​res/​laboratoare/​lab-05-tasks.zip|arhiva laboratorului]] este calculată suma primelor ''​num''​ numere naturale. 
 + 
 +Urmăriți codul, observați construcțiile și registrele specifice pentru lucru cu bytes. Rulați codul. 
 + 
 +<note important>​ 
 +Treceți la următorul pas doar după ce ați înțeles foarte bine ce face codul. Vă va fi greu să faceți următorul exercițiu dacă aveți dificultăți în înțelegerea exercițiului curent. 
 +</​note>​ 
 + 
 +==== [1.5p] 5. Suma pătratelor primelor N numere naturale ==== 
 + 
 +Porniți de la programul ''​sum_n.asm''​ și creați un program ''​sum_n_square.asm''​ care să calculeze suma pătratelor primelor ''​num''​ numere naturale. 
 + 
 +<note tip> 
 +Registrele ''​eax''​ și ''​edx''​ le veți folosi la înmulțirea pentru ridicarea la putere (în instrucțiunea ''​mul''​). Astfel că nu veți mai putea folosi (ușor) registrul ''​eax''​ pentru stocarea sumei pătratelor. Pentru a reține suma pătratelor aveți două variante: 
 +  - (mai simplu) Folosiți registrul ''​ebx''​ pentru a reține suma pătratelor. 
 +  - (mai complicat) Înainte de a opera registrul ''​eax''​ salvați valoarea sa pe stivă (folosind instrucțiunea ''​push''​),​ apoi faceți operațiile necesare și apoi restaurați valoarea salvată (folosind instrucțiunea ''​pop''​). 
 + 
 +</​note>​ 
 + 
 +<​note>​ 
 +Pentru verificare, suma pătratelor primelor ''​100''​ de numere naturale este ''​338350''​. 
 +</​note>​ 
 +==== [1p] 6. Tutorial: Suma elementelor dintr-un vector reprezentate pe un octet ====
  
 În programul ''​sum_array.asm''​ din [[http://​elf.cs.pub.ro/​asm/​res/​laboratoare/​lab-05-tasks.zip|arhiva laboratorului]] este calculată suma elementelor unui vector (//array//) de octeți (//bytes//, reprezentare pe 8 biți). În programul ''​sum_array.asm''​ din [[http://​elf.cs.pub.ro/​asm/​res/​laboratoare/​lab-05-tasks.zip|arhiva laboratorului]] este calculată suma elementelor unui vector (//array//) de octeți (//bytes//, reprezentare pe 8 biți).
Line 148: Line 186:
 </​note>​ </​note>​
  
- +==== [2p] 7. Suma elementelor dintr-un vector ====
-==== Suma elementelor dintr-un vector ====+
  
 În zona marcată cu ''​TODO''​ din fișierul ''​sum_array.asm''​ completați codul pentru a realiza suma vectorilor cu elemente de tip word (16 biți) și de tip dword (32 de biți); este vorba de vectorii ''​word_array''​ și ''​dword_array''​. În zona marcată cu ''​TODO''​ din fișierul ''​sum_array.asm''​ completați codul pentru a realiza suma vectorilor cu elemente de tip word (16 biți) și de tip dword (32 de biți); este vorba de vectorii ''​word_array''​ și ''​dword_array''​.
Line 164: Line 201:
 </​note>​ </​note>​
  
-==== Suma pătratelor ​elementelor ​dintr-un vector ====+<​note>​ 
 +Suma elementelor ​celor trei vectori trebuie să fie: 
 +  * ''​sum(byte_array):​ 575''​ 
 +  * ''​sum(word_array):​ 65799 ''​ 
 +  * ''​sum(dword_array):​ 74758117''​
  
-TODO+</​note>​
  
-==== Numărul de numere negative și pozitive într-un vector ====+==== [1.5p] 8. Suma pătratelor elementelor dintr-un vector ====
  
-TODO+Pornind de la programul de la exercițiul anterior, calculați suma pătratelor elementelor dintr-un vector.
  
-==== Numărul de numere pare șimpare într-un vector ====+<​note>​ 
 +Puteți folosi vectorul ''​dword_array''​ dar ar trebui să fie mai mici valorile elementelor ca să nu treacă pătratele valorilor acestora de reprezentarea pe 32 de biți
 +</​note>​
  
-TODO+<​note>​ 
 +Dacă folosiți construcția de mai jos (vector cu ''​10''​ elemente)<​code>​ 
 +    dword_array dd 1392, 12544, 7992, 6992, 7202, 27187, 28789, 17897, 12988, 17992 
 +</​code>​ 
 +suma pătratelor va fi ''​2704560839''​. 
 +</​note>​ 
 +==== [1.5p] 9. Bonus: Numărul de numere negative și pozitive dintr-un vector ==== 
 + 
 +Creați un program care afișează numărul de numere negative, respectiv numărul de numere pozitive dintr-un vector. 
 + 
 +<​note>​ 
 +Definiți un vector care să conțină atât numere negative cât și numare pozitive. 
 +</​note>​ 
 + 
 +<note tip> 
 +Folosiți intrucțiunea ''​cmp''​ și mnemonici de salt condițional. Urmăriți detalii [[https://​en.wikibooks.org/​wiki/​X86_Assembly/​Control_Flow|aici]]. 
 +</​note>​ 
 + 
 +<note tip> 
 +Intrucțiunea ''​inc''​ urmată de un registru incrementează cu ''​1''​ valoarea stocată în acel registru. 
 +</​note>​ 
 + 
 +==== [2p] 10. Bonus: Numărul de numere pare și impare dintr-un vector ==== 
 + 
 +Creați un program care afișează numărul de numere pare, respectiv numărul de numere impare dintr-un vector. 
 + 
 +<note tip> 
 +Puteți folosi instrucțiunea ''​div''​ pentru a împărți un număr la ''​2''​ și pentru a compara apoi restul împărțirii cu ''​0''​. Urmăriți detalii [[https://​en.wikibooks.org/​wiki/​X86_Assembly/​Arithmetic|aici]]. 
 + 
 +Va trebui să folosiți trei registre pentru împărțire:​ ''​EDX''​ și ''​EAX''​ pentru deîmpărțit,​ un alt registru pentru împărțitor (probabil ''​EBX''​). Ceea ce înseamnă că va trebui să salvați pe stivă, înaintea operației de împărțire,​ valorile celor două registre în care rețineți numărul de numere pare și numărul de numere impare. 
 +</​note>​ 
 + 
 +<​note>​ 
 +Pentru testare folosiți un vector doar cu numere pozitive. Pentru numere negative trebuie să faceți extensie de semn; ar merge și fără pentru că ne interesează doar restul, dar nu am fi riguroși :-) 
 +</​note>​
laboratoare/laborator-05.txt · Last modified: 2016/01/09 18:27 by razvan.deaconescu