MSDN のドキュメントによると、クラス関数の既定の__thiscall呼び出し規約を使用すると、"this" ポインターが ECX に格納されます。これは、通常の C++ コードを変換する場合には確かに当てはまりますが、インライン アセンブリで「this」にアクセスしようとしたときに問題が発生しました。
テストプログラムは次のとおりです。
#include <cstdio>
class TestClass
{
long x;
public:
inline TestClass(long x):x(x){}
public:
inline long getX1(){return x;}
inline long getX2()
{
_asm
{
mov eax,dword ptr[ecx]
}
}
};
int main()
{
TestClass c(42);
printf("c.getX1() = %d\n",c.getX1());
printf("c.getX2() = %d\n",c.getX2());
return 0;
}
2 つの Get 関数は次のように変換されます。
?getX1@TestClass@@QAEJXZ (public: long __thiscall TestClass::getX1(void)):
00000000: 8B 01 mov eax,dword ptr [ecx]
00000002: C3 ret
?getX2@TestClass@@QAEJXZ (public: long __thiscall TestClass::getX2(void)):
00000000: 8B 01 mov eax,dword ptr [ecx]
00000002: C3 ret
これら 2 つの機能は同一であると言っても過言ではありません。それでも、プログラムからの出力は次のとおりです。
c.getX1() = 42
c.getX2() = 1
明らかに、「これ」は2 番目の Get 関数が呼び出されたときに ECX に格納されないため、私の質問は次のとおりです。インライン アセンブリを含むクラス関数が呼び出し規則に従っていること、および/または通常/非インラインと同じ方法で呼び出されていることを確認するにはどうすればよいですか?機能?
編集: main 関数は次のように変換されます。
_main:
00000000: 51 push ecx
00000001: 6A 2A push 2Ah
00000003: 68 00 00 00 00 push offset $SG3948
00000008: E8 00 00 00 00 call _printf
0000000D: 83 C4 08 add esp,8
00000010: 8D 0C 24 lea ecx,[esp]
00000013: E8 00 00 00 00 call ?getX2@TestClass@@QAEJXZ
00000018: 50 push eax
00000019: 68 00 00 00 00 push offset $SG3949
0000001E: E8 00 00 00 00 call _printf
00000023: 33 C0 xor eax,eax
00000025: 83 C4 0C add esp,0Ch
00000028: C3 ret