User Tools

Site Tools


laboratoare:laborator-03

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
laboratoare:laborator-03 [2015/09/23 20:48]
vladimir.diaconescu [Exerciții]
laboratoare:laborator-03 [2016/10/16 23:51] (current)
mihai.tiganus [[10p] BONUS: Lab 2, Reloaded (in Assembly)]
Line 1: Line 1:
-====== Laborator 03 ======+====== Laborator 03: First baby steps ======
  
 În acest laborator, vom prezenta o parte din instrucțiunile x86, precum și o suită de exemple introductive. În acest laborator, vom prezenta o parte din instrucțiunile x86, precum și o suită de exemple introductive.
Line 29: Line 29:
  
 <code asm> <code asm>
-mov al, 12 <-> \xB0\x0C +mov al, 12 <​-> ​'\xB0\x0C' 
-xor dx, dx <-> \x66\x31\xD2 +xor dx, dx <​-> ​'\x66\x31\xD2' 
-jmp esp    <-> \xFF\xE4+jmp esp    <​-> ​'\xFF\xE4'
 </​code>​ </​code>​
  
Line 75: Line 75:
  
 Există cazuri în care se impun constrângeri asupra dimensiunii codului și/sau datelor, cum este cazul device-urilor specializate pentru un singur task, având puțină memorie. Din această categorie fac parte și driverele pentru dispozitive. Există cazuri în care se impun constrângeri asupra dimensiunii codului și/sau datelor, cum este cazul device-urilor specializate pentru un singur task, având puțină memorie. Din această categorie fac parte și driverele pentru dispozitive.
 +
 +=== Fun ===
 +
 +Pentru mai multe detalii, discutați asistentul vostru de laborator pentru a vă împărtăși experiența lui personală în materie de limbaj de asamblare și cazurile practice de utilizare folosite.
  
 ===== Familia x86 ===== ===== Familia x86 =====
Line 153: Line 157:
 ===== Exemple ===== ===== Exemple =====
 <​note>​ <​note>​
-Limbajul de asamblare x86 are două sintaxe oficiale: Intel și AT&T. Există o serie de [[https://​en.wikipedia.org/​wiki/​X86_assembly_language#​Syntax|diferențe]] între cele două. Sintaxa Intel este sprijinită de majoritatea asambloarelor. Din considerente de platformă și răspândire (și pentru că programatorii scriu a = 1, nu 1 = a), noi vom folosi sintaxa Intel pe parcursul laboratoarelor.+Limbajul de asamblare x86 are două sintaxe oficiale: Intel și AT&T. Există o serie de [[https://​en.wikipedia.org/​wiki/​X86_assembly_language#​Syntax|diferențe]] între cele două. Sintaxa Intel este sprijinită de majoritatea asambloarelor. Din considerente de platformă și răspândire (și pentru că programatorii scriu a = 1, nu 1 = a), noi vom folosi sintaxa Intel în cadrul laboratorului.
 </​note>​ </​note>​
 ==== Hello, World! ==== ==== Hello, World! ====
  
-Putem vedea un exemplu de program în limbaj de asamblare mai jos. Acesta va afișa, la consolă, string-ul ​"Hello, World!".+Putem vedea un exemplu de program în limbaj de asamblare mai jos. Acesta va afișa, la consolă, string-ul ​''​%%Hello, World!%%''​.
  
 <code asm> <code asm>
Line 169: Line 173:
 global CMAIN global CMAIN
 CMAIN: CMAIN:
-    ​sub esp, 4+    ​mov ebp, esp        ; Initialize frame pointer 
 +    lea eax, [myString] ; Load the effective address of our string into the eax register 
 +    push eax            ; Push the address unto the stack in order to pass it to '​puts'​ 
 +    call puts           ; Call the puts routine 
 +    pop eax             ; Retrieve eax from the stack 
 +    ret                 ; Return from the main routine 
 +</​code>​ 
 +==== JMP și JMP-if-condition ==== 
 +Fluxul programelor în limbaj de asamblare este controlat prin instrucțiuni de tip **jump**, un analog al lui **goto** din limbajul C. 
 + 
 +Instrucțiunea **jmp** va dirija fluxul programului spre adresa primită ca argument, fie direct, fie printr-un registru. 
 + 
 +Spre exemplu: 
 + 
 +<code asm> 
 +%include "​io.inc"​ 
 +extern puts 
 + 
 +section .data 
 +    string1: db "​You'​ll never get here!",​0 
 +    string2: db "​Nothing to see here.",​0 
 + 
 +section .text 
 +global CMAIN 
 +CMAIN: 
 +    mov ebp, esp 
 +    lea eax, [string2] 
 +    push eax 
 +    call puts 
 +    pop eax 
 +    jmp exit           ; Unconditional jump to the '​exit'​ label 
 +    lea eax, [string1] ; Code unreachable beyond this point 
 +    push eax 
 +    call puts 
 +    pop eax 
 +exit: 
 +    ret 
 +</​code>​ 
 + 
 +Așa cum am precizat, instrucțiunile de tip **jmp** pot primi ca argument un registru care să conțină adresa la care se va face salt, sau un offset relativ față de poziția curentă în program (sau, mai bine spus, față de registrul **eip**). 
 + 
 +Puteți urmări aceste două aspecte în exemplul de mai jos. 
 + 
 +<code asm> 
 +%include "​io.inc"​ 
 +extern puts 
 + 
 +section .data 
 +    string1: db "This looks convoluted",​0 
 +    string2: db "Where are we going?",​0 
 + 
 +section .text 
 +global CMAIN 
 +CMAIN: 
 +    mov ebp, esp 
 +    mov eax, zone2 
 +    jmp eax       ; jmp to whatever eax contains 
 +zone1: 
 +    lea eax, [string2] 
 +    push eax 
 +    call puts 
 +    pop eax 
 +    jmp exit 
 +zone2: 
 +    lea eax, [string1] 
 +    push eax 
 +    call puts 
 +    pop eax 
 +    jmp $-0x1c ​   ; relative offset jump 
 +exit: 
 +    ret 
 +</​code>​ 
 + 
 +<note important>​Ce reprezintă **$** în exemplul de mai sus? Dar valoarea **0x1c**?</​note>​ 
 + 
 +Instrucțiunile de tipul **jump-if-condition** se aseamănă cu **if** din C. Aceste instrucțiuni folosesc drept condiții indicatorii de stare din registrul ''​%%EFLAGS%%''​. E foarte important de ținut minte faptul că acest registru indică contextul de execuție al instrucțiunii curente și se modifică după fiecare instrucțiune. 
 + 
 +Pentru a exemplifica acest lucru, fie următorul program: 
 +<code asm> 
 +%include "​io.inc"​ 
 +extern puts 
 + 
 +section .data 
 +    myString: db "​Hello,​ World!",​0 
 + 
 +section .text 
 +global CMAIN 
 +CMAIN: 
 +    mov ebp, esp 
 +    mov eax, 1 
 +    mov ebx, 1 
 +    cmp eax, ebx 
 +    add ecx1   ; Delete this line 
 +    je print 
 +    ret 
 +print:
     lea eax, [myString]     lea eax, [myString]
-    ​mov [esp], ​eax+    ​push eax
     call puts     call puts
-    ​add esp, 4+    ​pop eax
     ret     ret
 </​code>​ </​code>​
-==== JMP-if-condition ==== + 
-TODO+Observați ce se întâmplă atunci când ștergeți instrucțiunea indicată. Instrucțiunea **je print** va face jump doar dacă ZF este setat. Instrucțiunea **cmp** face diferența dintre cei doi operanzi; dacă diferența este 0, atunci ZF va fi setat. În schimb, instrucțiunea **add ecx, 1** modifică valoarea lui ZF. De aceea, se recomandă ca instrucțiunile de tipul j//​condiție//​ să fie plasate imediat după instrucțiunile ce verifică condiția respectivă.
 ===== Exerciții ===== ===== Exerciții =====
  
 +==== 1. [20p] Conditional jumps ====
 +
 +Pornind de la exemplul anterior, ce modificări ar trebui făcute astfel încât afișarea mesajului să se facă numai dacă conținutul registrului **eax** este mai mare decât cel din **ebx**?
 +
 +==== 2. [40p] More hellos ====
 +  - [10p] Folosind programul ce afișează '​Hello,​ World!'​ de mai sus, încărcați adresa șirului în alt registru și puneți-l pe stivă. S-a schimbat ceva? De ce da/nu?
 +  - [10p] Modificați programul astfel încât să mai afișeze încă un mesaj ('​Goodbye,​ World!'​)
 +  - [20p] Folosind instrucțiuni de tip jump, modificați programul astfel încât să afișeze de 3 ori '​Hello,​ World!'​. Evitați ciclarea la infinit.
 +
 +==== 3. [40p] Grumpy jumps ====
 Fie următorul program. Fie următorul program.
  
Line 217: Line 326:
 </​code>​ </​code>​
  
-  - Modificați-l astfel încât la rularea lui să se afișeze mesajul ''​%%Well done!%%''​. Urmăriți comentariile marcate cu ''​%%TODO%%''​ +  - [30p] Modificați-l astfel încât la rularea lui să se afișeze mesajul ''​%%Well done!%%''​. Urmăriți comentariile marcate cu ''​%%TODO%%''​ 
-  - De ce, în continuare, se afișează și mesajul greșit? Ce lipsește?+  - [10p] De ce, în continuare, se afișează și mesajul greșit? Ce lipsește? 
 +==== [10p] BONUS: Fibonacci ==== 
 +Calculați al ''​eax''​-lea număr Fibonacci.
 ===== Resurse utile ===== ===== Resurse utile =====
 +* [[http://​savannah.nongnu.org/​projects/​pgubook/​|Programming from the Ground Up]]
 +* [[http://​beginners.re/​|Reverse Engineering for Beginners]]
 * [[http://​www.intel.com/​content/​dam/​www/​public/​us/​en/​documents/​manuals/​64-ia-32-architectures-software-developer-instruction-set-reference-manual-325383.pdf|Intel 64 and IA-32 Architectures Software Developer Manual]] * [[http://​www.intel.com/​content/​dam/​www/​public/​us/​en/​documents/​manuals/​64-ia-32-architectures-software-developer-instruction-set-reference-manual-325383.pdf|Intel 64 and IA-32 Architectures Software Developer Manual]]
 * [[http://​css.csail.mit.edu/​6.858/​2015/​readings/​i386.pdf|Intel 80386 Programmer'​s Reference Manual]] * [[http://​css.csail.mit.edu/​6.858/​2015/​readings/​i386.pdf|Intel 80386 Programmer'​s Reference Manual]]
 * [[http://​cs.stanford.edu/​people/​eroberts/​courses/​soco/​projects/​risc/​risccisc/​|RISC vs. CISC]] * [[http://​cs.stanford.edu/​people/​eroberts/​courses/​soco/​projects/​risc/​risccisc/​|RISC vs. CISC]]
 +* [[http://​unixwiz.net/​techtips/​x86-jumps.html|Intel x86 JUMP Quick Reference]]
laboratoare/laborator-03.1443030536.txt.gz · Last modified: 2015/09/23 20:48 by vladimir.diaconescu