Search

'CLKH64 OS'에 해당되는 글 37건

  1. 2013.01.19 11장 Calling convention, ABI

11장 Calling convention, ABI

CLKH64 OS/11장 2013. 1. 19. 12:15 Posted by 알 수 없는 사용자

 

1. IA32-e Calling Convention

11장 329페이지에 보면 IA32-e 에서의 calling convention은 기존의 x86과 3가지점에서 다르다.

- 파라미터를 전달할때 레지스터를 우선으로 사용(= fastcall)

: 파라미터의 타입에 따라 레지스터를 다르게 사용하는데 정수의 경우 RDI,RSI,RDX,RCX,R8,R9 순서로 6개 사용

: 실수 타입의 경우 XMM0 ~ XMM7(FPU) 순으로 8개 사용

: 파라미터 수가 넘어가면 보호모드와 마찬가지로 스택을 사용

- 두번째 차이는 리턴값을 담는 레지스터로 EAX가 아니라 RAX와 RDX를 사용.

- 세번째 차이는 레지스터 또는 스택에 파라미터를 삽입하는 순서. LTR(Left to Right)

: 여기서 의문이 생겼. 위키에 보면 RTL이라고 되어있는데? RTL이 그뜻이 아닌가?

(http://en.wikipedia.org/wiki/X86_calling_conventions)

 

검색해보니 파스칼이 LTR이 맞는걸 봐서 RTL과 LTR의 의미는 내가 알고 있는것과 동일했다.

그리고 저자가 책에 나온것은 System V AMD64, 즉 64비트 유닉스계열 시스템에서 사용하는 ABI에 해당되는 Calling convention이었다.

근데 RTL이라고 써있잖아?

 

그리고 Calling Convention을 따지는데 왜 GCC와 비쥬얼 스튜디오가 왜 나오고 ABI, Application Bianry Interface는 왜 따지는거지? 라는 생각이 들었다.

 

ABI가 뭔지 더 정확히 알아봐야 했다.

 

2. ABI, Application Binary Interface

이전에도 한번 포스팅 했었던것 같은데 그때 너무 간략히 해서 ABI가 뭔지 기억이 안났다. 위키를 찾아봤다.

In computer software, an application binary interface (ABI) describes the low-level interface between a computer program and the operating system or another program.

 

ABI는 프로그램과 - 운영체제, 또는 다른 프로그램과의 Interface다.

굉장히 추상적이다. 이게 무슨뜻인지 알기 어려웠다.

ABIs cover details such as:
  • data type, size, and alignment
  • the calling convention, which controls how functions' arguments are passed and return values retrieved; for example, whether all parameters are passed on the stack or some are passed in registers, which registers are used for which function parameters, and whether the first function parameter passed on the stack is pushed first or last onto the stack
  • how an application should make system calls to the operating system and, if the ABI specifies direct system calls rather than procedure calls to system call stubs, the system call numbers
  • and in the case of a complete operating system ABI, the binary format of object files, program libraries and so on.

A complete ABI, such as the Intel Binary Compatibility Standard (iBCS),[1] allows a program from one operating system supporting that ABI to run without modifications on any other such system, provided that necessary shared libraries are present, and similar prerequisites are fulfilled.

Other ABIs standardize details such as the C++ name mangling,[2] exception propagation,[3] and calling convention between compilers on the same platform, but do not require cross-platform compatibility.

An ABI should not be confused with an application programming interface (API) which defines a library of routines to call, data structures to manipulate, and/or object classes to use in the construction of an application using that particular (often language specific) API.

(참조 - http://en.wikipedia.org/wiki/Application_Binary_Interface)

ABI는 Calling Convention을 정의한다고 나와있었다. 좀 이해가 됐다. Calling convention 위키에서 왜 ABI를 따지는지.

그리고 ABI는 같은 플랫폼에서 컴파일러간 calling convention을 정의하기도 한다고 나와있다.

 

여기까지의 내용들을 바탕으로 내 생각을 정리 해 보자면

- Calling convention 등 ABI 에서 정의되는 것들은 플랫폼(CPU)과는 상관 없다. 오히려 운영체제가 정의하기에 달려 있다.

그리고 이렇게 운영체제가 정의한 대로 해당 운영체제에서 돌아갈 바이너리를 위해 설계된 컴파일러가 코드를 만들어 낸다.

- 그리고 시스템 콜을 사용하지 않는 독립적인 파일의 경우 서로 다른 Calling Convention을 가진 컴파일러에 의해 생성되더라도 같은 CPU, 운영체제 에서 돌아간다. 다시 말해서 Calling convention은 서로 다른 모듈간 상호 참조를 위한 것이다.

시스템 내에서 실행 가능성을 보장하는것은 시스템 콜을 이용하지 않는다면, Calling convention이 아니라 오브젝트 파일의 바이너리 포맷같은 것들이다. 시스템 콜과 Calling convention을 맞추어 줘야 하는 이유는 시스템 콜 또한 함수이기 때문이다.

- 시스템 내에서 바이너리 파일간 상호 호환성을 맞추기 위해서는 Calling convention, Name Mangling, 오브젝트 포맷등을 포함하는 ABI가 일치해야 한다.

-  만약 ABI 가 다르다면 함수 호출 규약이 다르다면, 파라미터가 잘못 전달되고, 레지스터를 잘못 사용하고, 리턴값이 잘못되고, 데이터 타입이 잘못 사용되는 등의 문제가 생긴다.

 

 

(참조 -  http://spikez.tistory.com/141)

 

여기까지가 일반론이다. 그렇다면 왜 우리가 System V AMD64 ABI를 따라야 할까?

이유는 간단했다.

 

우리가 사용하는 컴파일러가 GCC니까.

그리고 이 GCC는 System V AMD64 ABI에 맞추어 설계되었으니까.

우리가 컴파일하는 64비트 코드는 System V AMD64 ABI대로 코드를 만들것이고

이를 어셈블리어에서 호환성을 맞춰주기 위해 저렇게 코딩 하는것이다.

 

만약 Visual Studio였다면 MS x64 Calling convention을 사용해야 한다.

(MSDN - http://msdn.microsoft.com/en-us/library/ms235286(v=vs.80).aspx)

그리고 우리가 ABI를 만들고 싶다면, 해당 ABI를 설계하고 그에 맞게 코드를 만들어줄 컴파일러를 만들어야 한다는 결론이

생각났다. 컴파일러에서 Calling Convention만 세팅해줄 수 있지 않을까? 하는 생각도 들었다. 그럼 새로 만들 필요가 없을텐데.

 

그렇다면 이제 문제는 하나가 남았다. 왜 위키는 파라미터 순서가 RTL이고, 책은 LTR인가?

위키보다 더 정확한, 근본적인 문서를 찾아야 했다.

 

abi_sysV_amd64.pdf

(출처 - http://www.sco.com/developers/devspecs/)

이 문서를 찾을 수 있었다.

 

그리고 문서는 우리가 가진 책과 같이 LTR이라 설명하고 있었다.

 

3. Fastcall, Stdcall, Cdecl

1. Cdecl은 스택을 Caller가 정리하니까 가변인자가 가능. 그러나 스택 정리 코드가 여기저기 산재하여 오브젝트 크기가 커진다.

2. 반대로 Stdcall이나 Fastcall은 Callee가 스택을 정리하므로 가변인자가 불가능하고 오브젝트 크기가 작아짐.

3. Fastcall은 ECX, EDX 순서로 레지스터부터 사용. \

 

4. 기타 읽을 거리

IA64, EM64T, AMD64간 차이

http://mapoo.kr/entry/IA32-IA64-AMD64-EM64T-%EC%95%84%ED%82%A4%ED%85%8D%EC%B3%90-%EA%B4%80%EB%A0%A8-%EA%B8%80 

 

Windows x64 Calling Convention

http://www.altdevblogaday.com/2012/05/24/x64-abi-intro-to-the-windows-x64-calling-convention/ 

 

The history of calling conventions, part 1~5

http://blogs.msdn.com/b/oldnewthing/archive/2004/01/02/47184.aspx

http://blogs.msdn.com/b/oldnewthing/archive/2004/01/07/48303.aspx

http://blogs.msdn.com/b/oldnewthing/archive/2004/01/08/48616.aspx

http://blogs.msdn.com/b/oldnewthing/archive/2004/01/13/58199.aspx

http://blogs.msdn.com/b/oldnewthing/archive/2004/01/14/58579.aspx

'CLKH64 OS > 11장' 카테고리의 다른 글

오늘의 핫한 이슈, 가상메모리  (0) 2013.01.21
11장 깨달은거  (1) 2013.01.19
8042 datasheet  (0) 2013.01.19