This shows you the differences between two versions of the page.
Both sides previous revision Previous revision Next revision | Previous revision Next revision Both sides next revision | ||
laboratoare:laborator-07 [2015/11/24 16:03] catalin.vasile3004 [Exerciții] |
laboratoare:laborator-07 [2015/11/24 16:32] catalin.vasile3004 [[2p] 3. Înmulţirea cu 2 a unui număr mare/lung] |
||
---|---|---|---|
Line 193: | Line 193: | ||
{{http://truestorieswithgill.com/wp-content/uploads/2013/09/20130915-190532.jpg?200|}}\\ | {{http://truestorieswithgill.com/wp-content/uploads/2013/09/20130915-190532.jpg?200|}}\\ | ||
că ați putea folosi, de exemplu, registrele DX concatenat cu AX (DX:AX) pentru a împărți un număr de 32 de biți la 16 biți (sau, de ce nu, să împărțiți EDX:EAX la un operand de 32 de biți).\\ | că ați putea folosi, de exemplu, registrele DX concatenat cu AX (DX:AX) pentru a împărți un număr de 32 de biți la 16 biți (sau, de ce nu, să împărțiți EDX:EAX la un operand de 32 de biți).\\ | ||
- | Să zicem ca am vrea să reprezentăm numărul 444123 în DX:AX și că vrem să-l împărțim la 10 (care merge reprezentat și pe 16 biți). | + | Să zicem ca am vrea să reprezentăm numărul 4444123 în DX:AX și că vrem să-l împărțim la 10 (care merge reprezentat și pe 16 biți). |
- | Ne-ar returna corect restul (=3), DAR ne-ar rămâne câtul 444123 care nu poate fi reprezentat, pentru că eventualul cât se depozitează în AX, care poate reține o valoare maximă de 65 536, AX fiind un registru de 16 biți.\\ | + | Ne-ar returna corect restul (=3), DAR ne-ar rămâne câtul 444412 care nu poate fi reprezentat, pentru că eventualul cât se depozitează în AX, care poate reține o valoare maximă de 65 536, AX fiind un registru de 16 biți.\\ |
Acestă reprezentare de la **div** ne ajută, dar pe post de "reverse" "Carry" de la înmulțire. Dacă ar fi fost să faceți împărțirea ca în clasele primare a operației menționate anterior, probabil ați fi făcut-o cam așa:\\ | Acestă reprezentare de la **div** ne ajută, dar pe post de "reverse" "Carry" de la înmulțire. Dacă ar fi fost să faceți împărțirea ca în clasele primare a operației menționate anterior, probabil ați fi făcut-o cam așa:\\ | ||
{{http://elf.cs.pub.ro/asm/wiki-old/_media/tut/impartire.png}}\\ | {{http://elf.cs.pub.ro/asm/wiki-old/_media/tut/impartire.png}}\\ | ||
Line 244: | Line 244: | ||
Recomandarea ar fi să folosiţi operanzi de tip dword (32 biţi) când nu vi se menţionează explicit, în exerciţiu, tipul acestora. | Recomandarea ar fi să folosiţi operanzi de tip dword (32 biţi) când nu vi se menţionează explicit, în exerciţiu, tipul acestora. | ||
</note> | </note> | ||
- | 1. Implementaţi împărţirea unui număr cu puteri ale lui 2 fără a folosi instrucţiunea **div**. Datele de input ale programului vor fi: numărul deîmpărţit şi puterea la care se ridică 2.\\ | + | ==== [2p] 1. Împărţiri cu puteri ale lui 2 ==== |
- | 2. Următorul cod îşi propune să incrementeze un byte dintr-un număr, cât timp acesta nu se resetează la 0, folosind instrucţiuni pe operanzi de 8 biţi. După o rulare se poate observa însă ca programul nu se execută cu ne-am aştepta, mai exact rămâne în buclă infinită. **Fără a modifica tipul operanzilor**, corectaţi linia din loop care face incrementarea astfel încât programul să se termine şi la finalizarea lui să se afişeze **512**. | + | Implementaţi împărţirea unui număr cu puteri ale lui 2 fără a folosi instrucţiunea **div**. Datele de input ale programului vor fi: numărul deîmpărţit şi puterea la care se ridică 2. |
+ | ==== [2p] 2. Increment flags ==== | ||
+ | Următorul cod îşi propune să incrementeze un byte dintr-un număr, cât timp acesta nu se resetează la 0, folosind instrucţiuni pe operanzi de 8 biţi. După o rulare se poate observa însă ca programul nu se execută cu ne-am aştepta, mai exact rămâne în buclă infinită. **Fără a modifica tipul operanzilor**, corectaţi linia din loop care face incrementarea astfel încât programul să se termine şi la finalizarea lui să se afişeze **512**. | ||
<file asm inc.asm> | <file asm inc.asm> | ||
%include "io.inc" | %include "io.inc" | ||
Line 268: | Line 270: | ||
Uitaţi-vă ce FLAG-uri activeză instrucţiunea **[[http://www.jegerlehner.ch/intel/IntelCodeTable.pdf|inc]]**. | Uitaţi-vă ce FLAG-uri activeză instrucţiunea **[[http://www.jegerlehner.ch/intel/IntelCodeTable.pdf|inc]]**. | ||
</note> | </note> | ||
- | 3. Implementaţi înmulţirea unui număr cu 2, fără a folosi instrucţiunea **mul**. | + | ==== [2p] 3. Înmulţirea cu 2 a unui număr mare/lung ==== |
+ | Implementaţi înmulţirea unui număr cu 2, fără a folosi instrucţiunea **mul**. | ||
<note important> | <note important> | ||
- | Numărul **trebuie** să aibă cel puţin 5 bytes în alcătuirea sa. | + | 1. Numărul **trebuie** să aibă cel puţin 5 bytes în alcătuirea sa. |
+ | 2. Trebuie să folosiţi instrucţiunea OR. | ||
</note> | </note> | ||
- | 4. Pornind de la scheletul de cod următor, implementaţi suma elementelor ale unui vector folosind **registre de 8 biţi (obligatoriu)**: | + | ==== [2p] 4. Suma elementelor (fără semn) ale unui vector ==== |
+ | Pornind de la scheletul de cod următor, implementaţi suma elementelor ale unui vector folosind **registre de 8 biţi (obligatoriu)**: | ||
<file asm sum.asm> | <file asm sum.asm> | ||
%include "io.inc" | %include "io.inc" | ||
Line 289: | Line 294: | ||
ret | ret | ||
</file> | </file> | ||
- | 5. Scrieţi o secvenţă de cod astfel încât să înmulţiţi **nr1** cu **nr2** şi să depuneţi rezultat în variabila **result**. **Trebuie** să folosiţi registre de 8 biţi. | + | ==== [2p] 5. Înmulţirea corectă a 2 numere de lungimi diferite ==== |
+ | Scrieţi o secvenţă de cod astfel încât să înmulţiţi **nr1** cu **nr2** şi să depuneţi rezultat în variabila **result**. **Trebuie** să folosiţi registre de 8 biţi. | ||
<file asm mul.asm> | <file asm mul.asm> | ||
%include "io.inc" | %include "io.inc" | ||
Line 308: | Line 314: | ||
</file> | </file> | ||
- | 6. BONUS: Pornind de la scheletul de cod următor, implementaţi suma elementelor (**cu semn**) ale unui vector folosind **registre de 8 biţi (obligatoriu)**: | + | ==== [1p] 6. BONUS: Suma elementelor (cu semn) ale unui vector ==== |
- | <file asm signed_sum> | + | Pornind de la scheletul de cod următor, implementaţi suma elementelor (**cu semn**) ale unui vector folosind **registre de 8 biţi (obligatoriu)**: |
+ | <file asm signed_sum.asm> | ||
%include "io.inc" | %include "io.inc" | ||
section .data | section .data | ||
Line 325: | Line 332: | ||
ret | ret | ||
</file> | </file> | ||
+ | ==== [1p] 7. BONUS: Împărţirea a 2 numere de lungimi diferite ==== | ||
+ | Realizaţi împărţirea corectă a lui **nr1** la **nr2** folosind **registre de maxim 16 biţi**: | ||
+ | <file asm div.asm> | ||
+ | %include "io.inc" | ||
+ | section .data | ||
+ | nr1: dd 4444123 | ||
+ | nr2: dw 10 | ||
+ | result: dd 0 | ||
+ | section .text | ||
+ | global CMAIN | ||
+ | CMAIN: | ||
+ | ; TODO divide nr1 by nr2 | ||
+ | ; by using registers of size up to 16 bits and | ||
+ | ; store the result in the "result" variable | ||
+ | |||
+ | PRINT_UDEC 4, result ; should be 444412 | ||
+ | |||
+ | xor eax, eax | ||
+ | ret | ||
+ | </file> | ||
+ | ==== [1p] 8. BONUS: Îmbunătăţire înmulţiri cu 2 ==== | ||
+ | [[http://www.jegerlehner.ch/intel/IntelCodeTable.pdf|Observaţi]] şi utilizaţi instrucţiunile de rotire, în locul celor de tip AND si OR, pentru a rezolva exerciţiului 3. | ||
+ | ==== [1p] 9. BONUS: Generalizare înmulţiri cu puteri ale lui 2 ==== | ||
+ | Modificaţi exerciţiul 3 astfel încât numărul să se poată înmulţi cu o variaţie mai mare de puteri ale lui 2 (cu aceleaşi limitări ca la 3). | ||