2009. 1. 30. 02:48
     

크악... 이제 슬슬 쉘을 만들까 해서 sprintf() 함수를 구현하고 있었습니다. 처음에는 cdecl을 강제로 줘서 예전에 스택 어드레스로 하던 가변 인자 처리 방법을 써볼까 했는데... 64bit gcc는 cdecl을 줘도 무시하더군요. ㅡ_ㅡa... 그것도 당당히 무시한다는 경고까지 띄우고 말입니다. ㅡ_ㅡa...

그래서 결국 중계 역할을 하는 함수를 하나 둬서, 함수 Call 시에 레지스터로 넘어간 파라메터를 스텍에 집어 넣은 후  sprintf() 함수를 불렀습니다. 스택에 파라메터가 다 들어가 있으니 당연히 예전 방식대로 처리할 수 있었지요. ;) 그런데 의외의 곳에서 낭패를 봤습니다. ㅡ_ㅡa.... 다음 코드를 보시죠. ㅠㅠ


아시는 분은 아시겠지만, “...”으로 함수 파라메터를 정의했다면 다른 함수로 “...” 을 넘겨줄 수 없습니다. 쿨럭..;;; 왜 이걸 생각 못했는지... 그래서 예전에 쓰던 va_arg() 시리즈 물은 혹시 잘 될까 싶어서 써 봤는데... 의외로 링크 에러가 안 나는 겁니다. 그래서 정의된 곳으로 가서 확인했더니 라이브러리 함수가 아닌 builtin 함수를 가리키고 있더군요. ㅡ_ㅡa... 그냥 바로 코드로 전환되어서 링크 에러가 안 났던... ㅠㅠ

진작 이놈들을 썼으면 훨씬 전에 끝났을 텐데... vsprintf() 함수나 구현하고 sprintf()랑 printf()는 vaprintf()를 사용하도록 변경해야겠군요. Calling Convention 때문에 고민 꽤나 했었는데... 왠지 허무합니다. ㅠㅠ 에궁... 이렇게 또 하루를 날려 먹는다는... 그나저나 매번 가변 인자 때문에 고생했었는데, 좋은 걸 알았네요. ㅎㅎ 이제 걱정 안해도 되겠습니다. ;)

아우... 일단 자고 내일 일찍 와서 마무리를 해야겠습니다. 그럼 다들 좋은 밤 되세요. ;)


ps) CharSyam님이 지적하신 내용을 보고 본문을 다시 읽어봤더니, va_arg()를 라이브러 함수인 것 처럼 표현해서, 약간 수정했습니다. 본래의 의도는 va_arg()가 지시하는 함수가 라이브러리 함수가 아니라 builtinXXX 시리즈 함수라는 뜻이었는데, 마치 va_arg() 자체가 함수라는 것 처럼 썼더군요. va_arg() 시리즈는 매크로가 맞습니다. ;) CharSyam님 감사합니다. ;)


Android App

Posted by 호기심 많은 kkamagui(까마귀, 한승훈)

댓글을 달아 주세요

  1. CharSyam 2009.01.30 11:07  댓글주소  수정/삭제  댓글쓰기

    built in 이 아니고 매크로 아니었나요? ㅎㅎㅎ
    전, 그것도 다 만들었었는데, 소스가 아주 간단해서 ㅎㅎㅎ
    보고 빼꼈죠. 고운 하루되세요.

    • Favicon of http://mint64os.pe.kr BlogIcon kkamagui 2009.01.30 16:16  댓글주소  수정/삭제

      GCC에서 va_arg() 매크로 시리즈가 bultinXXX()로 정의되어있던데, builtinXXX()도 함수가 아니라 매크로인가요? 이건 유심히 안봤는데 한번 봐야겠군요. ;)

      저도 예전 32bit OS 때는 매번 구현했었는데, 64bit 같은 경우는 fastcall 처럼 몇몇 레지스터를 사용해서 함수를 콜하기 때문에 보호 모드 처럼 스택을 기반으로 따라가면서 사용할 수가 없더군요. 굳이 하려면 중간 함수를 거쳐서 파라메터를 스택에 넣어주는 일을 해야하는데 해보니 여간 귀찮은 일이 아니더라구요. ㅠㅠ

      va_list를 사용하면 스택에 넣고 따라가는 작업을 할 필요가 없으니 편리하지요. ㅎㅎ va_list 짱~!!