User Tools

Site Tools


laboratoare:laborator-07

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
Next revision Both sides next revision
laboratoare:laborator-07 [2015/11/24 16:03]
catalin.vasile3004 [Exerciții]
laboratoare:laborator-07 [2015/11/25 17:47]
catalin.vasile3004 [Adunare. Generalizare.]
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 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. 
 +<note tip>​Instrucţiunile **shl** şi **shr** pot folosi registrul **CL** pentru a specifica numărul de shiftări.</​note>​ 
 +==== [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 271:
 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 ​corectă numere de lungimi diferite ==== 
-<note important>​ +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. 
-Numărul ​**trebuie** să aibă cel puţin 5 bytes în alcătuirea sa. +<file asm mul.asm>
-</​note>​ +
-4. 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 1256, 93, 44, 55, 23, 44, 71, 43 +    ​nr1: dB 0x900x02 ; =656 
-    ​lendd $-v +    ​nr2dB 0x04 
-    ​sumdW 0+    ​resultdw 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>​
-5Scrieţ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] 4Suma elementelor (fără semn) ale unui vector ==== 
-<file asm mul.asm>+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
-    ​nr1: dB 0x900x02 ; =656 +    ​v: dB 1256, 93, 44, 55, 23, 44, 71, 43 
-    ​nr2dB 0x04 +    ​lendd $-v 
-    ​resultdw 0+    ​sumdW 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>​
  
-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 333:
     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 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).
  
laboratoare/laborator-07.txt · Last modified: 2015/11/30 22:53 by razvan.deaconescu