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> | ||