This shows you the differences between two versions of the page.
Both sides previous revision Previous revision Next revision | Previous revision Last revision Both sides next revision | ||
laboratoare:laborator-07 [2015/11/24 16:24] catalin.vasile3004 [[1p] 2. Increment flags] |
laboratoare:laborator-07 [2015/11/27 18:38] razvan.deaconescu [Sign bit. Left padding.] |
||
---|---|---|---|
Line 109: | Line 109: | ||
; loop code: | ; loop code: | ||
for: | for: | ||
- | mov eax, byte [A + ecx*4] ; get a digit from A | + | mov eax, dword [A + ecx*4] ; get a digit from A |
- | adc eax, byte [B + ecx*4] ; AL = A + B + Carry | + | adc eax, dword [B + ecx*4] ; AL = A + B + Carry |
mov [result + ecx*4], eax ; store result | mov [result + ecx*4], eax ; store result | ||
inc ecx | inc ecx | ||
Line 128: | Line 128: | ||
===== Sign bit. Left padding. ===== | ===== Sign bit. Left padding. ===== | ||
+ | |||
După cum ştiţi, la numerele reprezentate în formă zecimală, se poate face padding în faţa numărului cu un set de cifre infinite de zero (de exemplu: 0000343 este fi acelaşi număr cu 343). Este perfect valabil şi la numerele reprezentate în binar, pot fi prefixate de oricâte cifre de zero (0010000100 este fix acelaşi număr ca 10000100).\\ | După cum ştiţi, la numerele reprezentate în formă zecimală, se poate face padding în faţa numărului cu un set de cifre infinite de zero (de exemplu: 0000343 este fi acelaşi număr cu 343). Este perfect valabil şi la numerele reprezentate în binar, pot fi prefixate de oricâte cifre de zero (0010000100 este fix acelaşi număr ca 10000100).\\ | ||
- | Apare în schimb o situaţie dubioasă la numerele negative datorită felului în care sunt reprezentate în binar. Dacă vă mai aduceţi aminte, acestea se reprezintă în complet faţă de 2.\\ | + | Apare în schimb o situaţie dubioasă la numerele negative datorită felului în care sunt reprezentate în binar. Dacă vă mai aduceţi aminte, acestea se reprezintă în complement faţă de 2.\\ |
Înainte să vă zic un fact concret, haideţi să vedem cum evoluează reprezentarea numerelor negative la stânga, cu cât se apropie mai mult de zero:\\ | Înainte să vă zic un fact concret, haideţi să vedem cum evoluează reprezentarea numerelor negative la stânga, cu cât se apropie mai mult de zero:\\ | ||
{{:laboratoare:nr_negative.png|}}\\ | {{:laboratoare:nr_negative.png|}}\\ | ||
Line 246: | Line 247: | ||
==== [2p] 1. Împărţiri cu puteri ale lui 2 ==== | ==== [2p] 1. Împărţiri cu puteri ale lui 2 ==== | ||
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. | 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. | ||
+ | <note tip>Instrucţiunile **shl** şi **shr** pot folosi registrul **CL** pentru a specifica numărul de shiftări.</note> | ||
==== [2p] 2. Increment flags ==== | ==== [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**. | 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**. | ||
Line 270: | Line 272: | ||
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> | ||
- | ==== [2p] 3. Înmulţirea cu 2 a unui număr mare/lung ==== | + | ==== [2p] 3. Înmulţirea corectă a 2 numere de lungimi diferite ==== |
- | Implementaţi înmulţirea unui număr cu 2, fără a folosi instrucţiunea **mul**. | + | 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. |
- | <note important> | + | <file asm mul.asm> |
- | Numărul **trebuie** să aibă cel puţin 5 bytes în alcătuirea sa. | + | |
- | </note> | + | |
- | ==== [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> | + | |
%include "io.inc" | %include "io.inc" | ||
section .data | section .data | ||
- | v: dB 12, 56, 93, 44, 55, 23, 44, 71, 43 | + | nr1: dB 0x90, 0x02 ; =656 |
- | len: dd $-v | + | nr2: dB 0x04 |
- | sum: dW 0 | + | result: dw 0 |
section .text | section .text | ||
global CMAIN | global CMAIN | ||
CMAIN: | CMAIN: | ||
- | ; TODO sum vector of BYTE elements into "sum" WORD variable | + | ; TODO multiply nr1 by nr2 using only 8bit registers |
+ | ; store the result in the "result" variable | ||
| | ||
- | PRINT_UDEC 2, sum ; should be 441 if result is correct | + | PRINT_UDEC 2, result ; should be 2624 |
| | ||
xor eax, eax | xor eax, eax | ||
ret | ret | ||
</file> | </file> | ||
- | ==== [2p] 5. Înmulţirea corectă a 2 numere de lungimi diferite ==== | + | ==== [2p] 4. Suma elementelor (fără semn) ale unui vector ==== |
- | 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. | + | Pornind de la scheletul de cod următor, implementaţi suma elementelor ale unui vector folosind **registre de 8 biţi (obligatoriu)**: |
- | <file asm mul.asm> | + | <file asm sum.asm> |
%include "io.inc" | %include "io.inc" | ||
section .data | section .data | ||
- | nr1: dB 0x90, 0x02 ; =656 | + | v: dB 12, 56, 93, 44, 55, 23, 44, 71, 43 |
- | nr2: dB 0x04 | + | len: dd $-v |
- | result: dw 0 | + | sum: dW 0 |
section .text | section .text | ||
global CMAIN | global CMAIN | ||
CMAIN: | CMAIN: | ||
- | ; TODO multiply nr1 by nr2 using only 8bit registers | + | ; TODO sum vector of BYTE elements into "sum" WORD variable |
- | ; store the result in the "result" variable | + | |
| | ||
- | PRINT_UDEC 2, result ; should be 2624 | + | PRINT_UDEC 2, sum ; should be 441 if result is correct |
| | ||
xor eax, eax | xor eax, eax | ||
ret | ret | ||
</file> | </file> | ||
+ | ==== [2p] 5. Î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> | ||
+ | - Numărul **trebuie** să aibă cel puţin 5 bytes în alcătuirea sa. | ||
+ | - Trebuie să folosiţi instrucţiunea OR. | ||
+ | </note> | ||
==== [1p] 6. BONUS: Suma elementelor (cu semn) ale unui vector ==== | ==== [1p] 6. BONUS: Suma elementelor (cu semn) ale unui vector ==== | ||
Line 351: | Line 354: | ||
ret | ret | ||
</file> | </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 cu Carry, în locul celor de tip AND si OR, pentru a rezolva exerciţiului 5. | ||
+ | ==== [1p] 9. BONUS: Generalizare înmulţiri cu puteri ale lui 2 ==== | ||
+ | Modificaţi exerciţiul 5 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 5). | ||