4 static void func static int counter 0

  • Slides: 37
Download presentation

4 static • Как у нас сохраняется значение: void func () { static int

4 static • Как у нас сохраняется значение: void func () { static int counter = 0; counter++; printf("%dn", counter); } int main (int argc, char** argv ) { func(); } Выведет: 1 2 3

8 Где они? Стандарт C: • at the end of the evaluation of a

8 Где они? Стандарт C: • at the end of the evaluation of a full expression (a full expression is an expression statement, or any other expression which is not a subexpression within any larger expression); • at the ||, &&, ? : , and comma operators; • at a function call (after the evaluation of all the arguments, and just before the actual call).

12 int some_global = 4; func 2() { } func 3() { int_3 func

12 int some_global = 4; func 2() { } func 3() { int_3 func 1(); } void func 1() { int_1; func 2(); func 3(); } //доступ только к int_1 и global void main ( int argc , char** argv ) { int_main; //отсюда есть доступ к global и int_main func 1(); }

16 Stack frame void myproc(int argument 1) { int a, b; /*код*/ } Вызываем

16 Stack frame void myproc(int argument 1) { int a, b; /*код*/ } Вызываем функцию: myproc(42); 1. push argument 1 (42) 2. call myproc 3. push ebp 4. mov ebp, esp 5. sub esp, 8 Рост стека ESP 8 байт под локальные переменные EBP Начало предыдущего кадра Адрес возврата argument 1 = 42

27 Простая программа int _cdecl main(int argc, char** argv) { int result = 0;

27 Простая программа int _cdecl main(int argc, char** argv) { int result = 0; char* str = "stringy!"; result++; return 0; }

28 TITLE f: ? ? ? ? ? Visual Studio 2008Projectssimplemain. c. 686 P

28 TITLE f: ? ? ? ? ? Visual Studio 2008Projectssimplemain. c. 686 P include listing. inc. model flat INCLUDELIB OLDNAMES $SG-5 DB 'stringy!', 00 H PUBLIC _main _TEXT SEGMENT _str$ = -8 ; size = 4 _result$ = -4 ; size = 4 _argc$ = 8 ; size = 4 _argv$ = 12 ; size = 4 _main PROC ; COMDAT ; 1 : int _cdecl main(int argc, char** argv) { 00000 55 push ebp 00001 8 b ec mov ebp, esp 00003 83 ec 08 sub esp, 8

29 ; 2 : int result = 0; 00006 c 7 45 fc 00

29 ; 2 : int result = 0; 00006 c 7 45 fc 00 00 mov DWORD PTR _result$[ebp], 0 ; 3 : char* str = "stringy!"; 0000 d c 7 45 f 8 00 00 mov DWORD PTR _str$[ebp], OFFSET $SG-5 ; 4 : result++; 00014 8 b 45 fc mov eax, DWORD PTR _result$[ebp] 00017 83 c 0 01 add eax, 1 0001 a 89 45 fc mov DWORD PTR _result$[ebp], eax ; 5 : return 0; 0001 d 33 c 0 xor eax, eax ; 6 : } 0001 f 8 b e 5 mov esp, ebp 00021 5 d pop ebp 00022 c 3 ret 0 _main ENDP _TEXT ENDS END

30 TITLE f: ? ? ? ? ? Visual Studio 2008Projectssimplemain. c. 686 P

30 TITLE f: ? ? ? ? ? Visual Studio 2008Projectssimplemain. c. 686 P include listing. inc. model flat INCLUDELIB OLDNAMES $SG-5 DB 'stringy!', 00 H PUBLIC _main _TEXT SEGMENT _str$ = -8 ; size = 4 _result$ = -4 ; size = 4 _argc$ = 8 ; size = 4 _argv$ = 12 ; size = 4 _main PROC ; COMDAT

31 ; 1 : int _cdecl main(int argc, char** argv) { 00000 55 push

31 ; 1 : int _cdecl main(int argc, char** argv) { 00000 55 push ebp 00001 8 b ec mov ebp, esp 00003 83 ec 08 sub esp, 8 ; sizeof(int) + sizeof(char*) = 4 + 4 = 8 ; 2 : int result = 0; 00006 c 7 45 fc 00 00 mov DWORD PTR _result$[ebp], 0 ; 3 : char* str = "stringy!"; 0000 d c 7 45 f 8 00 00 mov DWORD PTR _str$[ebp], OFFSET $SG-5 ; 4 : result++; 00014 8 b 45 fc mov eax, DWORD PTR _result$[ebp] 00017 83 c 0 01 add eax, 1 0001 a 89 45 fc mov DWORD PTR _result$[ebp], eax ; 5 : return 0; 0001 d 33 c 0 xor eax, eax ; 6 : } 0001 f 8 b e 5 mov esp, ebp 00021 5 d pop ebp 00022 c 3 ret 0 _main ENDP _TEXT ENDS // затем END

32 Программа с printf и дополнительной функцией void printf(const char*, . . . );

32 Программа с printf и дополнительной функцией void printf(const char*, . . . ); int _cdecl foosize (char* param_str) { register int size = 0; while(param_str[size++]); return size; } int _cdecl main(int argc, char** argv) { int result = 0; char* str = "stringy!"; result = foosize(str); printf("%d", result); return 0; }

34 Программа с printf и дополнительной функцией void printf(const char*, . . . );

34 Программа с printf и дополнительной функцией void printf(const char*, . . . ); int _cdecl foosize (char* param_str) { register int size = 0; while(param_str[size++]); return size; } int _cdecl main(int argc, char** argv) { int result = 0; char* str = "stringy!"; result = foosize(str); printf("%d", result); return 0; }

35 _TEXT SEGMENT _size$ = -4 _param_str$ = 8 _foosize PROC ; size =

35 _TEXT SEGMENT _size$ = -4 _param_str$ = 8 _foosize PROC ; size = 4 ; COMDAT ; 3 : int _cdecl foosize (char* param_str) { 00000 55 push ebp 00001 8 b ec mov ebp, esp 00003 51 push ecx ; 4 : register int size = 0; 00004 c 7 45 fc 00 00 mov DWORD PTR _size$[ebp], 0 $LN 2@foosize: ; 5 : while(param_str[size++]); /* код для while*/ ; 6 : return size; 00023 8 b 45 fc mov eax, DWORD PTR _size$[ebp] ; 7 : } 00026 8 b e 5 mov esp, ebp 00028 5 d pop ebp 00029 c 3 ret 0 _foosize ENDP

36 Программа с printf и дополнительной функцией void printf(const char*, . . . );

36 Программа с printf и дополнительной функцией void printf(const char*, . . . ); int _cdecl foosize (char* param_str) { register int size = 0; while(param_str[size++]); return size; } int _cdecl main(int argc, char** argv) { int result = 0; char* str = "stringy!"; result = foosize(str); printf("%d", result); return 0; }

37 из функции main ; 13 : result = foosize(str); 00014 00017 00018 0001

37 из функции main ; 13 : result = foosize(str); 00014 00017 00018 0001 d 00020 8 b 45 f 8 50 e 8 00 00 83 c 4 04 89 45 fc ; 14 : printf("%d", result); 00023 00026 00027 0002 c 00031 8 b 4 d fc 51 68 00 00 e 8 00 00 83 c 4 08 ; 15 : return 0; 00034 33 c 0 mov push call add mov eax, DWORD PTR _str$[ebp] eax _foosize esp, 4 DWORD PTR _result$[ebp], eax mov push call add ecx, DWORD PTR _result$[ebp] ecx OFFSET $SG-6 _printf esp, 8 xor eax, eax