printf("%d\n", add(a, b));
코드 중 add()함수를 호출하는 과정입니다
add() 함수는 두 개의 매개변수를 호출하고 있습니다

[EBP-8]에 있는 값은 b에 해당하는 2이며 [EBP-4]에 있는 값은 a에 해당하는 1입니다
b, a순으로 스택에 PUSH하고 있습니다

스택 상태를 확인한다면 위와 같습니다
EBP-10과 EBP-C은 함수 호출을 위한 변수 선언입니다
이제 add() 함수 내부로 들어갔습니다

CALL 명령어가 실행되어 해당 함수로 들어가기 전에 CPU는 무조건 해당 함수가 종료될 때 복귀할 주소(return address)를 스택에 저장합니다
복귀 주소의 값은 401041로 add() 함수가 종료 된 후 다음 명령어의 주소입니다
long add(long a, long b)
{
add() 함수가 실행되면 다음과 같이 스택 프레임이 생성됩니다
CALL 명령어 실행 후 401000 주소로 이동했습니다

처음에 add() 함수 만의 스택 프레임을 생성합니다
00401000 PUSH EBP
00401001 MOV EBP, ESP
main() 함수의 EBP 값을 스택에 저장 후 현재의 ESP를 EBP에 입력합니다


main()에서 사용되었던 EBP 값(19FF28)을 스택에 백업 후 EBP값은 새롭게 0019FF10으로 설정되었습니다
long x = a, y = b;
add() 함수의 로컬 변수 x, y에 각각 파라미터 a, b를 대입합니다
00401003 SUB ESP,8
로컬 변수 x, y에 대해서 스택 메모리 영역(8바이트)을 확보합니다

add() 함수에서 새롭게 스택 프레임이 생성되어 EBP 값이 변경되었습니다
따라서 [EBP+8]과 [EBP+C]는 각각 파라미터 a, b를 가리킵니다
[EBP-8], [EBP-4]는 각각 add() 함수의 로컬 변수 x, y를 의미합니다
return (x + y);

명령 실행 후 EAX에는 [EBP-8](변수 x의 값 =1)이 입력되며 ADD 명령어를 통해 EAX에 변수 y의 값 ([EBP-4] = 2)을 더해서 EAX에 저장합니다
현재 EAX의 값은 3이 됩니다
EAX는 범용 레지스터로 산술연산에 사용되며 함수의 리턴 값으로도 사용됩니다
return (x + y);
}
이제 add() 함수가 리턴됩니다
그 전에 add() 함수가 생성하였던 스택 프레임을 해제 합니다

MOV ESP, EBP
현재 EBP 값을 ESP에 대입합니다
즉 add() 함수를 시작할 때의 ESP 값(19FF10)을 EBP에 넣어 두었다가 함수 종료 시 ESP를 원래대로 복원시키는 목적으로 사용합니다
POP EBP
add() 함수가 시작되면서 스택에 백업한 EBP 값을 복원합니다
복원된 EBP 값은 19FF28이며, 이 값은 main() 함수의 EBP 값입니다
이제 add() 함수의 스택 프레임은 해제가 되었습니다

현재 ESP 값은 0019FF14이며 그 주소의 값은 401041입니다
이 값은 앞에서 CALL 명령에서 CPU가 스택에 저장한 복귀 주소 입니다
0040101B RETN
리턴 명령어가 실행되면 스택에 저장된 복귀 주소로 리턴합니다
실행이후 스택의 모습은 아래와 같습니다

add() 함수 호출하기 전의 스택 상태로 돌아왔습니다
이제 main() 함수로 이동하였습니다
다음 명령어는
ADD ESP, 8
입니다

스택에서 19FF18과 19FF1C 주소의 내용은 add() 함수 사용 시 파라미터 a, b가 저장되어 있습니다
add() 함수는 종료되었고 해당 파라미터는 사용할 이유가 없기 때문에 ESP에 8을 더하여 스택을 정리하는 것입니다
위와 같이 함수를 호출한 쪽(Caller)에서 파라미터를 정리하는 것을 'cdecl' 방식이라고 합니다
호출 당하는 쪽(Callee)에서 파라미터를 정리하는 것을 'stdcall' 방식이라고 합니다
이러한 함수 호출 규약을 일컬어 Calling Convention이라고 말합니다
printf("%d\n", add(a, b));

401044 주소의 EAX 레지스터에는 add() 함수에서 저장된 리턴 값(3)이들어 있습니다
40104A 주소의CALL 401067 함수는 C 표준 라이브러리 printf() 함수 입니다
40104F 주소에 ADD ESP, 8 명령으로 스택에서 함수 파라미터를 정리하고 있습니다
00401052 XOR EAX, EAX
main() 함수의 리턴 값(0)을 세팅합니다
XOR 연산은 같은 값끼리 진행하면 0이되는 특징이 있습니다
메인 함수가 종료되기 전에 마찬가지로 스택 프레임을 해제 합니다

00401054 MOV ESP, EBP
00401056 POP EBP
두 명령어로 인해서 main() 함수의 스택 프레임은 해제 되었습니다

이후 스택의 모습은 위 사진과 같습니다
마지막으로 main() 함수가 종료(리턴)되면서 리턴 주소 (00401250)으로 점프합니다