This shows you the differences between two versions of the page.
Both sides previous revision Previous revision Next revision | Previous revision | ||
laboratoare:laborator-04 [2015/11/04 09:17] vladimir.diaconescu Fixed typo; numbered exercises |
laboratoare:laborator-04 [2015/11/11 08:56] (current) razvan.deaconescu [Alte resurse] |
||
---|---|---|---|
Line 3: | Line 3: | ||
În acest laborator vom prezenta modul în care se realizează apeluri de funcții. Vom vedea cum putem folosi instrucțiunile ''call'' și ''ret'' pentru a realiza apeluri de funcții și cum folosim stiva pentru a transmite parametrii unei funcții. | În acest laborator vom prezenta modul în care se realizează apeluri de funcții. Vom vedea cum putem folosi instrucțiunile ''call'' și ''ret'' pentru a realiza apeluri de funcții și cum folosim stiva pentru a transmite parametrii unei funcții. | ||
- | Laboratorul este de forma //learn by doing// partea practică alterând între secțiuni de tip tutorial, cu parcurgere pas cu pas și prezentarea soluției, și exerciții care trebuie să fie rezolvate. | + | Laboratorul este de forma //learn by doing// partea practică alternând între secțiuni de tip tutorial, cu parcurgere pas cu pas și prezentarea soluției, și exerciții care trebuie să fie rezolvate. |
===== Mediul de lucru ===== | ===== Mediul de lucru ===== | ||
Line 44: | Line 44: | ||
După cum spuneam, în final, totul ajunge în limbaj de asamblare. Adesea ajungem să avem acces doar la codul obiect al unor programe și vrem să inspectăm modul în care arată. | După cum spuneam, în final, totul ajunge în limbaj de asamblare. Adesea ajungem să avem acces doar la codul obiect al unor programe și vrem să inspectăm modul în care arată. | ||
- | Pentru a observa acest lucru, haideți să compilăm până la codul obiect un program scris în C și apoi să-l dezamblăm. Este vorba de programul ''test.c'' din arhiva de laborator. | + | Pentru a observa acest lucru, haideți să compilăm până la codul obiect un program scris în C și apoi să-l dezasamblăm. Este vorba de programul ''test.c'' din arhiva de laborator. |
Pentru a compila un program vom folosi linia de comandă și de acolo comanda ''cl'' care reprezintă compilatorul și linker-ul din Visual Studio. | Pentru a compila un program vom folosi linia de comandă și de acolo comanda ''cl'' care reprezintă compilatorul și linker-ul din Visual Studio. | ||
Line 60: | Line 60: | ||
cl /c test.c | cl /c test.c | ||
</code> | </code> | ||
- | În urma rulării comenzii de mai sus în directorul curent vom avea fișierul obiect test.c. | + | În urma rulării comenzii de mai sus în directorul curent vom avea fișierul obiect test.obj. |
Putem obține și forma în limbaj de asamblare a acestuia folosind comanda<code> | Putem obține și forma în limbaj de asamblare a acestuia folosind comanda<code> | ||
Line 75: | Line 75: | ||
Veți obține un output similar celui de mai jos<code> | Veți obține un output similar celui de mai jos<code> | ||
- | C:\Program Files (x86)\SASM\MinGW\bin>.\objdump.exe -d C:\Users\razvan\test.obj | + | C:\Program Files (x86)\SASM\MinGW\bin>.\objdump.exe -d -M intel C:\Users\razvan\test.obj |
C:\Users\razvan\test.obj: file format pe-i386 | C:\Users\razvan\test.obj: file format pe-i386 | ||
Line 83: | Line 83: | ||
00000000 <_main>: | 00000000 <_main>: | ||
- | 0: 55 push %ebp | + | 0: 55 push ebp |
- | 1: 8b ec mov %esp,%ebp | + | 1: 8b ec mov ebp,esp |
- | 3: 6a 0f push $0xf | + | 3: 6a 0f push 0xf |
5: e8 00 00 00 00 call a <_main+0xa> | 5: e8 00 00 00 00 call a <_main+0xa> | ||
- | a: 83 c4 04 add $0x4,%esp | + | a: 83 c4 04 add esp,0x4 |
- | d: 50 push %eax | + | d: 50 push eax |
- | e: 68 00 00 00 00 push $0x0 | + | e: 68 00 00 00 00 push 0x0 |
13: e8 00 00 00 00 call 18 <_main+0x18> | 13: e8 00 00 00 00 call 18 <_main+0x18> | ||
- | 18: 83 c4 08 add $0x8,%esp | + | 18: 83 c4 08 add esp,0x8 |
- | 1b: 33 c0 xor %eax,%eax | + | 1b: 33 c0 xor eax,eax |
- | 1d: 5d pop %ebp | + | 1d: 5d pop ebp |
1e: c3 ret | 1e: c3 ret | ||
1f: cc int3 | 1f: cc int3 | ||
00000020 <_first_func>: | 00000020 <_first_func>: | ||
- | 20: 55 push %ebp | + | 20: 55 push ebp |
- | 21: 8b ec mov %esp,%ebp | + | 21: 8b ec mov ebp,esp |
- | 23: 51 push %ecx | + | 23: 51 push ecx |
- | 24: c7 45 fc 03 00 00 00 movl $0x3,-0x4(%ebp) | + | 24: c7 45 fc 03 00 00 00 mov DWORD PTR [ebp-0x4],0x3 |
- | 2b: 68 00 00 00 00 push $0x0 | + | 2b: 68 00 00 00 00 push 0x0 |
30: e8 00 00 00 00 call 35 <_first_func+0x15> | 30: e8 00 00 00 00 call 35 <_first_func+0x15> | ||
- | 35: 83 c4 04 add $0x4,%esp | + | 35: 83 c4 04 add esp,0x4 |
- | 38: 8b 45 fc mov -0x4(%ebp),%eax | + | 38: 8b 45 fc mov eax,DWORD PTR [ebp-0x4] |
- | 3b: 50 push %eax | + | 3b: 50 push eax |
- | 3c: 8d 4d 08 lea 0x8(%ebp),%ecx | + | 3c: 8d 4d 08 lea ecx,[ebp+0x8] |
- | 3f: 51 push %ecx | + | 3f: 51 push ecx |
40: e8 00 00 00 00 call 45 <_first_func+0x25> | 40: e8 00 00 00 00 call 45 <_first_func+0x25> | ||
- | 45: 83 c4 08 add $0x8,%esp | + | 45: 83 c4 08 add esp,0x8 |
- | 48: 8b 45 08 mov 0x8(%ebp),%eax | + | 48: 8b 45 08 mov eax,DWORD PTR [ebp+0x8] |
- | 4b: 8b e5 mov %ebp,%esp | + | 4b: 8b e5 mov esp,ebp |
- | 4d: 5d pop %ebp | + | 4d: 5d pop ebp |
4e: c3 ret | 4e: c3 ret | ||
4f: cc int3 | 4f: cc int3 | ||
00000050 <_second_func>: | 00000050 <_second_func>: | ||
- | 50: 55 push %ebp | + | 50: 55 push ebp |
- | 51: 8b ec mov %esp,%ebp | + | 51: 8b ec mov ebp,esp |
- | 53: 8b 45 08 mov 0x8(%ebp),%eax | + | 53: 8b 45 08 mov eax,DWORD PTR [ebp+0x8] |
- | 56: 8b 08 mov (%eax),%ecx | + | 56: 8b 08 mov ecx,DWORD PTR [eax] |
- | 58: 03 4d 0c add 0xc(%ebp),%ecx | + | 58: 03 4d 0c add ecx,DWORD PTR [ebp+0xc] |
- | 5b: 8b 55 08 mov 0x8(%ebp),%edx | + | 5b: 8b 55 08 mov edx,DWORD PTR [ebp+0x8] |
- | 5e: 89 0a mov %ecx,(%edx) | + | 5e: 89 0a mov DWORD PTR [edx],ecx |
- | 60: 5d pop %ebp | + | 60: 5d pop ebp |
- | 61: c3 ret | + | 61: c3 |
</code> | </code> | ||
Line 160: | Line 160: | ||
</code> | </code> | ||
- | În primă fază am plasat pe stivă argumentul funcției ''puts'' adică adresa șirului ''msg''. Apoi am apelat funcția ''puts''. Apoi am restaurat stiva (care crescuse prin apelul ''push'') scăzând ''4'' octeți (dimensiunea unui cuvânt pe 32 de biți) din registrul de stivă (''esp''). | + | În primă fază am plasat pe stivă argumentul funcției ''puts'' adică adresa șirului ''msg''. Apoi am apelat funcția ''puts''. Apoi am restaurat stiva (care crescuse prin apelul ''push'') adăugând ''4'' octeți (dimensiunea unui cuvânt pe 32 de biți) la registrul de stivă (''esp''). |
Astfel sunt traduse majoritatea apelurilor de funcții. Dacă urmărim dezasamblarea fișierul ''test.obj'' putem observa acest șablon de apel și în alte părți. Mai jos sunt secvențele extrase din dezasamblarea de mai sus:<code> | Astfel sunt traduse majoritatea apelurilor de funcții. Dacă urmărim dezasamblarea fișierul ''test.obj'' putem observa acest șablon de apel și în alte părți. Mai jos sunt secvențele extrase din dezasamblarea de mai sus:<code> | ||
Line 203: | Line 203: | ||
Pașii de urmat sunt: | Pașii de urmat sunt: | ||
- Marcarea simbolului ''printf'' ca simbol extern. | - Marcarea simbolului ''printf'' ca simbol extern. | ||
- | - Definirea șirului de formatare ''%%"String lengths is %u", 13, 10, 0%%''. | + | - Definirea șirului de formatare ''%%"String length is %u", 13, 10, 0%%''. |
- Realizarea apelului funcției ''printf'', adică: | - Realizarea apelului funcției ''printf'', adică: | ||
- Punerea celor două argumente pe stivă: șirul de formatarea și lungimea. | - Punerea celor două argumente pe stivă: șirul de formatarea și lungimea. | ||
Line 343: | Line 343: | ||
în care să rețineți fie lungimea totală a șirului (de la începutul până la ultimul ''NUL''-byte), fie numărul de șiruri din array. | în care să rețineți fie lungimea totală a șirului (de la începutul până la ultimul ''NUL''-byte), fie numărul de șiruri din array. | ||
</note> | </note> | ||
+ | ===== Soluții ===== | ||
+ | |||
+ | [[http://elf.cs.pub.ro/asm/res/laboratoare/lab-04-sol.zip|Soluții de referință pentru exercițiile de laborator]] | ||
+ | |||
===== Alte resurse ===== | ===== Alte resurse ===== | ||
* [[http://www.nasm.us/|nasm]] | * [[http://www.nasm.us/|nasm]] | ||
* [[http://dman95.github.io/SASM/english.html|SASM]] | * [[http://dman95.github.io/SASM/english.html|SASM]] |