Turbo-C
C++Builder  |  Delphi  |  FireMonkey  |  C/C++  |  Free Pascal  |  Firebird
볼랜드포럼 BorlandForum
 경고! 게시물 작성자의 사전 허락없는 메일주소 추출행위 절대 금지
터보-C 포럼
Q & A
FAQ
팁&트릭
강좌/문서
자료실
Lua 게시판
볼랜드포럼 홈
헤드라인 뉴스
IT 뉴스
공지사항
자유게시판
해피 브레이크
공동 프로젝트
구인/구직
회원 장터
건의사항
운영진 게시판
회원 메뉴
북마크
볼랜드포럼 광고 모집

C/C++ Q/A
[3260] Re:Re:Re:감사합니다... 한가지 더 어쭤 보겠습니다....
Starlet [starlet5] 2944 읽음    2004-03-12 20:26
안녕하세요. va_start, va_arg 가 갯수를 알 수없는 "..." 에 해당하는 인자를 받아오는 것입니다.. 그런데 va_arg를 사용하지 않고 구현하신다고요? 그러면 va_arg가 하는일을 직접 구현해야 겠지요. %d만을 사용한다면 굉장히 간단해 집니다.
va_arg를 구현하기 위해서는 C 가 함수 호출전 파라미터를 전달하는 방식을 알면 간단합니다. printf 함수 호출전 함수에 전달되는 파라미터들을 뒤에서 부터 차례대로 스택에 넣습니다.

printf(buf, 1, 2, 3); 이라면 3, 2, 1, buf주소 순으로 push됩니다. 그러면 스택은 아래와 같겠죠? (16bit 환경이라 가정하고 스택이 0xFFFF부터 시작)

0xFFF9 buf주소
0xFFFB 1
0xFFFD 2
0xFFFF 3

그럼 buf의 주소를 이용해 파라미터를 차례대로 알 수 있습니다. C에서 포인터를 사용해서 한다면...

testfunc(char *buf, ...)
{
   int *p;

   p = (int *) &buf;      // 스택상 buf의 위치를 p에 넣습니다.
   printf("%d\n", *(p+1));   // 1이 출력됩니다.
   printf("%d\n", *(p+2));   // 2가 출력됩니다.
  
p에 스택상 buf의 주소를 대입시킵니다. p+1을 하면 p가 integer 포인터이기 때문에 16bit상에서 2bytes가 증가하게 됩니다. 그래서 0xFFFB 위치의 값 1을 가리킵니다.
위와 같이 buf의 주소로 buf 다음에 오는 파라미터가 몇개인던지간에 가져올 수 있습니다. 파라미터 수보다 %d가 더 많으면 push된 파라미터들 이상의 메모리를 가리켜 메모리 오류가 나겠죠?
va_arg도 위와 같은 방식으로 이루어집니다. 그리고 실제로 Borland C++ 내에 구현된 vsprintf도 위와 같은 방식으로 va_arg를 사용해 구현된 것입니다. Borland C++ 에 있는 printf를 가지고 %d를 더많게 해보시면 똑같이 메모리 오류가 나는것을 보실 수 있습니다.

도움이 되시길 바랍니다.

+ -

관련 글 리스트
3256 printf() 함수의 소스코드 구할수 없을까요??? 워니 2314 2004/03/11
4376     Re:printf() 함수의 소스코드 구할수 없을까요??? 조준회 3445 2004/03/11
3257     Re:printf() 함수의 소스코드 구할수 없을까요??? Starlet 9399 2004/03/11
3259         Re:Re:감사합니다... 한가지 더 어쭤 보겠습니다.... 워니 2637 2004/03/12
3260             Re:Re:Re:감사합니다... 한가지 더 어쭤 보겠습니다.... Starlet 2944 2004/03/12
3265                 Re:Re:Re:Re:감사합니다.. 도움 많이 됐습니다.. 님.. 행복하세요~~ *냉무) 워니 2273 2004/03/17
Google
Copyright © 1999-2015, borlandforum.com. All right reserved.