Entry Code , Exit Code |
▶ 함수가 시작하고 끝날때 항상 붙음. ▶ Entry Code , Exit Code 를 다른 명령어로도 표현 할 수 있다. |
__cdecl 과 __stdcll 호출 규약의 차이점 |
▶ __cdecl 규약 호출을 해서 인자가 스택영역에 쌓이는 순서는 오른쪽에서 왼쪽으로 쌓인다. 호출을 한 장소 ( 여기서는 main ) 에서 값을 꺼낸다. 스택 반환 작업을 호출자쪽에서 ( ebp = ebp + 8 ) 한다. ▶ __stdcall 규약 호출을 해서 인자가 스택영역에 쌓이는 순서는 오른쪽에서 왼쪽으로 쌓인다. 스택 반환 작업을 호출당한 쪽(피호출자)에서 ( ebp = ebp + 8 ) 한다. ▶ 둘의 차이점 __cdecl과 __stdcall의 가장 큰 차이점은 스택 정리 주체가 누구인가하는 점인데 사실 이 차이점이 컴파일된 결과 코드에 미치는 영향은 별로 없다. 스택 정리 주체와는 상관없이 스택은 항상 호출 전의 상태로 복구되며 프로그램의 동작도 완전히 동일하다. 실행 속도는 거의 차이가 없으며 프로그램의 크기는 비록 무시할만한 수준이기는 하지만 __stdcall이 조금 더 작다. 왜냐하면 함수를 여러 번 호출하더라도 스택을 정리하는 코드는 함수 끝의 접미에 딱 한 번만 작성되기 때문이다. 반면 __cdecl은 호출원이 스택을 정 리하므로 호출할 때마다 정리 코드가 반복되어 프로그램 크기가 조금 더 커진다. 또 다른 중요한 차이점은 가변 인수 함수를 만들 수 있는가 아닌가 하는 점이다. __stdcall은 함수가 직접 스택을 정리하기 때문에 가변 인수 함수를 지원하지 않는다. 함수 접미에 스택 정리 코드를 작성하려면 인수의 총 크기를 미리 알아야 하는데 가변 인수 함수는 전달되는 인수 개수가 가변이므로 이 크기가 고정적이지 않아 접미에서 스택을 직접 정리할 수 없다. 컴파일러가 접미의 ret n 명령에 대해 n을 결정할 수 없는 것이다. 이에 비해 __cdecl은 함수가 스택을 정리할 책임이 없으며 호출원이 함수를 부를 때마다 스택을 정리한다. 함수를 호출하는 쪽에서는 인수를 몇개나 전달했는지 알 수 있으므로 실제 전달한 인수 크기만큼 스택을 정리할 수 있다. 그래서 printf나 scanf같은 가변 인수를 지원하는 함수는 모두 __cdecl 호출 규약을 사용한다. 또한 윈도우즈 API 함수의 기본 호출 규약은 __stdcall이지만 wsprintf는 예외적으로 __cdecl로 작성되어 있다. 호출 규약 중 호출원이 스택을 정리하는 것은 __cdecl밖에 없으며 그래서 가변 인수를 지원할 수 있는 호출 규약도 __cdecl이 유일하다. 가변 인수 함수를 만들려면 반드시 __cdecl 호출 규약을 사용해야 한다. 만약 가변 인수 함수를 __stdcall로 작성하면 컴파일러는 이를 무시하고 __cdecl로 강제로 바꾸어 버린다. |
C , ASM Mix |
▶ Asm 과 C 파일을 연결해서 사용한 경우 현재 Code 영역의 함수호출을 할때 Linux 안의 인자가 int * 즉, &iNum 이므로 이 값을 ebp 를 움직여 스택영역(메모리)안의 위치를 가르켜, eax 안에다가 저장해놓고 ( iNum 의 주소 ) 이 register 를 이용해 값을 저장해 ( [eax]<- 값, ebx ) 다시 화면에 출력해주는 과정 |
'Assembly' 카테고리의 다른 글
2013.09.24_Assambly 메모리에 레지->CPU 에 다시 넣어서 무한 반복 하는 소스 (0) | 2013.09.24 |
---|---|
2013.09.23_어셈블리_ 메모리에 변수값직접넣기 (0) | 2013.09.23 |
2013.09.11_스택영역을 확인해보자_스크랩 (0) | 2013.09.12 |
2013.09.11_CODE Stack 영역 알아보기_수정중 (0) | 2013.09.12 |
2013.09.10_ASM_push_instructions, pop_instructions (0) | 2013.09.10 |