2013-07-29 4 views
1

call 명령어를 C++ 코드의 GNU 인라인 어셈블러를 통해 사용하는 경우, 내가 알고있는 함수를 호출하려면 __stdcall 규칙을 사용합니다. 어떤 레지스터도 clobbered로 나열해야합니까?GNU 인라인 asm : 어떤 레지스터가 __stdcall에 의해 clobbered됩니까?

나는 인터넷에서 훌륭한 지침을 찾지 못했지만, %eax, %edx%ecx은 호출자 저장이며 이전 두 개는 반환 값으로 예약되어 있습니다.

여기 내 코드가 있습니다. 세 번째 콜론 뒤에 무엇이 필요한지 알고 싶습니다. ...

#include <cstdint> 

namespace { 

inline uint64_t invoke_stdcall(uint64_t (* stdcall_func)()) 
{ 
    unsigned long hi32, lo32; 
    asm(
     "call %2" 
     : "=d" (hi32), "=a" (lo32) 
     : "m" (stdcall_func) 
     : /* HELP! What goes here? */ 
    ); 
    return static_cast<uint64_t>(hi32) << 32 | static_cast<uint32_t>(lo32); 
} 

} // anonymous namespace 

This message thread 내가 인터넷에서 찾을 수있는 가장 좋은,하지만 난 "이 __stdcall는 저장하지 않고 수정할 수 있습니다 가정 것입니다"라고 아무것도 찾을 수가 없었다

+1

각 플랫폼에는 다른 제약 조건이 있습니다 (예 : Windows와 Linux는 32와 64 비트는 물론, 동일한 요구 사항을 갖지 않습니다). 내가 찾은 최고의 리소스는 [Agner Fog의 C++ 호출 규칙] (http://www.agner.org/optimize/calling_conventions.pdf)이며, 원하는 정보를 제공합니다. – syam

+1

Wikipedia도 꽤 좋습니다 : http://en.wikipedia.org/wiki/X86_calling_conventions –

+0

Thx both. @Mats, Wiki에서 "함수 내에서 사용하도록 지정된"어떤 이유로 든 나를 위해 명시 적으로는 충분하지 않았지만, 그것은 그들이 말하는 것임에 틀림 없습니다. – 0xbe5077ed

답변

2

MS EAX, EDX 및 ECX는 호출에 의해 "파괴"되고 다른 모든 레지스터는 호출자가 32 비트 코드 인 link to MSDN docs에 보존해야한다고 설명합니다. 어떤 호출 규칙이 사용되는지는 중요하지 않습니다.

그래서, 명확하게하기 위해, 당신은 eaxedx가 이미 인라인 어셈블러에서 사용되기 때문에 등의 Clobbered ecx를 표시해야합니다.

및 x86-64에 대한

이 문서는 here이며,

(가) RBX, RBP, RDI, RSI, R12, R13, R14를 등록 말한다, 및 R15는 비 휘발성 간주되며 저장해야합니다 및 복원 그것들을 사용하는 함수에 의해.