This shows you the differences between two versions of the page.
|
iocla:cursuri:capitol-07:demo:04 [2016/12/03 19:05] laura.vasilescu |
— (current) | ||
|---|---|---|---|
| Line 1: | Line 1: | ||
| - | ===== 4. Funcții ===== | ||
| - | |||
| - | Dorim să înțelegem cum se fac apelurile de funcții. | ||
| - | |||
| - | ==== Exemple în C ==== | ||
| - | Vom scrie programe în C pe care le vom compila folosind consola MINGW pentru a putea observa assembly-ul generat. | ||
| - | |||
| - | Deschideți consola MINGW. (''C:\MinGW\msys\1.0\msys.bat'') | ||
| - | |||
| - | |||
| - | ^ Fără apel de funcție ^ Cu apel simplu de funcție ^ | ||
| - | |<code c test1.c> | ||
| - | #include <stdio.h> | ||
| - | |||
| - | void f(void) { | ||
| - | } | ||
| - | |||
| - | int main(void) | ||
| - | { | ||
| - | //f(); | ||
| - | |||
| - | return 0; | ||
| - | }</code>|<code c test2.c> | ||
| - | #include <stdio.h> | ||
| - | |||
| - | void f(void) { | ||
| - | } | ||
| - | |||
| - | int main(void) | ||
| - | { | ||
| - | f(); | ||
| - | |||
| - | return 0; | ||
| - | }</code>| | ||
| - | |||
| - | Rulăm următoarele două comenzi: | ||
| - | <code bash> | ||
| - | $ gcc -S -O0 -masm=intel -o test1.asm test1.c | ||
| - | $ gcc -S -O0 -masm=intel -o test2.asm test2.c | ||
| - | </code> | ||
| - | |||
| - | |< 20em 20% 20%>| | ||
| - | ^ Fără apel de funcție ^ Cu apel simplu de funcție ^ | ||
| - | |<code asm test1.asm> .file "test.c" | ||
| - | .intel_syntax | ||
| - | .text | ||
| - | .globl _f | ||
| - | .def _f; .scl 2; .type 32; .endef | ||
| - | _f: | ||
| - | push ebp | ||
| - | mov ebp, esp | ||
| - | pop ebp | ||
| - | ret | ||
| - | .def ___main; .scl 2; .type 32; .endef | ||
| - | .globl _main | ||
| - | .def _main; .scl 2; .type 32; .endef | ||
| - | _main: | ||
| - | push ebp | ||
| - | mov ebp, esp | ||
| - | sub esp, 8 | ||
| - | and esp, -16 | ||
| - | mov eax, 0 | ||
| - | add eax, 15 | ||
| - | add eax, 15 | ||
| - | shr eax, 4 | ||
| - | sal eax, 4 | ||
| - | mov DWORD PTR [ebp-4], eax | ||
| - | mov eax, DWORD PTR [ebp-4] | ||
| - | call __alloca | ||
| - | call ___main | ||
| - | mov eax, 0 | ||
| - | leave | ||
| - | ret | ||
| - | </code>|<code asm test2.asm> .file "test.c" | ||
| - | .intel_syntax | ||
| - | .text | ||
| - | .globl _f | ||
| - | .def _f; .scl 2; .type 32; .endef | ||
| - | _f: | ||
| - | push ebp | ||
| - | mov ebp, esp | ||
| - | pop ebp | ||
| - | ret | ||
| - | .def ___main; .scl 2; .type 32; .endef | ||
| - | .globl _main | ||
| - | .def _main; .scl 2; .type 32; .endef | ||
| - | _main: | ||
| - | push ebp | ||
| - | mov ebp, esp | ||
| - | sub esp, 8 | ||
| - | and esp, -16 | ||
| - | mov eax, 0 | ||
| - | add eax, 15 | ||
| - | add eax, 15 | ||
| - | shr eax, 4 | ||
| - | sal eax, 4 | ||
| - | mov DWORD PTR [ebp-4], eax | ||
| - | mov eax, DWORD PTR [ebp-4] | ||
| - | call __alloca | ||
| - | call ___main | ||
| - | call _f | ||
| - | mov eax, 0 | ||
| - | leave | ||
| - | ret | ||
| - | </code>| | ||
| - | <hidden> | ||
| - | j) Exemplu simplu cu apel de funcții în assembly (fără parametri, fără variabile locale, fără ebp) | ||
| - | --- Ce fac instrucțiunile call și ret, salvarea adresei de retur (adresa următoarei instrucțiuni) | ||
| - | k) Exemplu simplu cu funcție fără parametri din care să înțeleagă rolul frame pointer-ului | ||
| - | --- Rolul frame pointer-ul: prologul și epilogul unei funcții (push ebp; mov ebp, esp; ... ; leave / mov esp, ebp; ret) | ||
| - | --- Frame pointer-ul este folosit ca să refere variabile locale | ||
| - | --- Calling convention 32 bit: parametri pe stivă | ||
| - | l) Exemplu assembly: printf cu un un parametru | ||
| - | --- Restaurarea stivei după apelul funcției | ||
| - | m) Exemplu assembly: printf cu un doi parametri | ||
| - | n) Exemplu de o funcție care întoarce ceva (în registrul eax) | ||
| - | </hidden> | ||