вход в функцию и выход

Чтобы немного начать понимать что же делает та или иная команда на языке С или директива или оператор рано или поздно придется посмотреть формируемых ассемблерный код.

Здесь немного рассмотрим инструкции , которые в первую очередь представляют интерес. Нас интересует в первую очередь как происходит вод в функцию и выход.

Вот пример неболшой функции :

void func1()
{
    int y=0;
    printf("%d",y);
}

void func1()
{
   0:	55                   	push   %ebp
   1:	89 e5                	mov    %esp,%ebp
   3:	83 ec 28             	sub    $0x28,%esp
    int y=0;
   6:	c7 45 f4 00 00 00 00 	movl   $0x0,-0xc(%ebp)
    printf("%d",y);
   d:	8b 45 f4             	mov    -0xc(%ebp),%eax
  10:	89 44 24 04          	mov    %eax,0x4(%esp)
  14:	c7 04 24 00 00 00 00 	movl   $0x0,(%esp)
			17: dir32	.rdata
  1b:	e8 00 00 00 00       	call   20 
			1c: DISP32	printf
}
  20:	c9                   	leave  
  21:	c3                   	ret    
  22:	90                   	nop    
  23:	90                   	nop

Конечно перед началом выполнения функции мы должны как-то сохранить адрес выхода из функции :

push сохранение в стеке "базового указателя" для вашего фрейма стека

mov %esp,%ebp перенос esp в ebp .

sub $0x28,%esp оставляет место для локальных переменных.

.......

leave выполняет работу по восстановлению фрейма стека вызывающей функции. (по сути pop %ebp ).

ret передает управление по адресу в ebp .