2012.05.25 01:00
     

근 한달동안 모든 코딩을 어셈블리어로만 하고 있다보니 호출 규약(Calling Convention)을 다시 살펴보고 있습니다. C로 프로그래밍하던 시절에는 호출 규약은 별로 신경쓰지 않았는데, 어셈블리어로 함수를 호출하려니 안 볼수가 없더군요. ㅠㅠ


MINT64 OS를 만들 때 어셈블리어로 코딩했으면서 왠 엄살이냐고 생각하실텐데... 리눅스에서 사용하는 호출 규약(Calling Convention)과 윈도우에서 사용하는 호출 규약은 상당한 차이가 있더라구요. ㅠㅠ 그래서 적응하는데 살짝 힘들었습니다. 사실 적응한다기 보다는 차이를 아는데 시간이 좀 걸렸지요. ㅠㅠ

64비트 리눅스의 호출 규약

리눅스는 64비트 모드에서 파라미터를 전달할 때 윈도우보다 레지스터를 더 많이 사용합니다. 정수 타입의 파라미터를 전달할 때는 순서대로 RDI, RSI, RDX, RCX, R8, R9까지 6개의 레지스터를 사용하고 7개 이상이면 스택을 통해 전달합니다. 실수 타입의 파라미터의 경우는 XMM0 ~ XMM7까지 8개를 순서대로 사용하고 그 이상이면 스택으로 전달하지요. ;)


반환값은 정수일 때 RAX(하위 64비트), RDX(상위 64비트)를 사용하고, 실수일때는 XMM0(하위 128비트), XMM1(상위 128비트)를 사용합니다. 아래는 64비트 멀티코어 OS 원리와 구조의 11.2.2 장에서 추출한 호출 규약 그림입니다. ;)




64비트 윈도우의 호출 규약

반면, 윈도우는 64비트 모드에서 파라미터를 전달할 때 레지스터 4개만 사용합니다. 정수 타입의 경우는 순서대로 RCX, RDX, R8, R9를 사용하고 나머지는 스택으로 전달합니다. 실수의 경우는 XMM0 ~ XMM3까지 4개를 순서대로 사용하며 나머지는 스택으로 전달합니다. 여기까지 보면 파라미터로 사용하는 레지스터의 종류와 개수만 차이가 나는 것 같습니다만.... 실제로 보면 스택을 사용하는 방법도 차이가 있습니다.


리눅스의 경우 파라미터를 전달할 때 스택을 꽉꽉 채워서 사용하는 반면, 윈도우의 경우는 4개의 레지스터가 들어갈 공간만큼을 띄워서 사용합니다. 즉, 파라미터 4개가 RCX, RDX, R8, R9를 통해 전달되지만, 스택에 이 4개를 위한 공간을 할당해놓는 것이죠. 아래 그림을 보시면 좀 더 이해하시기 편할 겁니다. ^^;;;





이 차이 때문에 한참을 헤맸네요. ㅠㅠ 스택에 저 공간을 안 할당해놓으면 파라미터가 잘못 전될되서 보기좋게 함수 호출이 실패를... 쿨럭..;;; 그리고 주의할 점은 비록 파라미터가 4개 미만이더라도 함수 호출 시 저 영역은 무조건 할당해야 한다는 겁니다. 에궁... 진짜 알고나면 별 것 아닌데... 코드를 몇 번이나 갈아 엎었는지 모르겠네요. ㅠㅠ


C로 코딩을 했으면 아예 신경을 안써도 되는 부분인데... 어셈블리어로 코딩하다보니 삽질을 하고 말았군요. ㅎㅎ 윈도우 호출 규약에 대한 보다 자세한 내용이 궁금하시다면 MSDN 사이트를 참고하시기 바랍니다. ^^


그나저나 PE32 파일 포멧을 읽어 메모리에 로딩하여 실행하는 가볍게 어셈블리어로 작성하는 괴수(?)를 어떻게해야 따라잡을 수 있을까요? 아우... 따라가려니 죽을 것만 같네요. ㅠㅠ


그럼 좋은 밤 되세요 ;)

Mittm

Android App

Posted by kkamagui

댓글을 달아 주세요

  1. Favicon of http://lunapiece.net BlogIcon Lyn 2012.06.05 18:27 신고  댓글주소  수정/삭제  댓글쓰기

    흑... 넘 어려워요

    • Favicon of http://kkamagui.tistory.com BlogIcon kkamagui 2012.06.12 23:54 신고  댓글주소  수정/삭제

      조금 복잡하긴 합니다만... ㅠㅠ 언젠가 직접 어셈블리어로 윈도우 코드를 작성할 일이 있으시면 그때 참고하셔도 될 것 같아요 ;)

      C로 프로그램을 작성하시는 분께는 사실 크게 중요하지 않은 부분이거든요 ^^;;;

  2. 2실독거노인 2013.02.05 17:10 신고  댓글주소  수정/삭제  댓글쓰기

    역시~ ㅋㅋ
    정리를 잘 해주신 덕분에 필요한 정보만 쏙 가지고 도망갑니다.
    답례로 매점에서 맛난 것 사드릴게요.

  3. Favicon of http://ian-tales.tistory.com BlogIcon IanTales 2018.01.18 14:24 신고  댓글주소  수정/삭제  댓글쓰기

    즉 리눅스는 함수호출시 스택공간을 해당 파라미터에 무관하게 꽉꽉 채워넣어서 공간을 받는데,
    윈도우는 얼마나 쓰던지간에 추가공간을 미리 할당시켜두지 않으면 함수호출자체가 안된다는 거군요...


티스토리 툴바