memset()と同じように、メモリのブロックを指定した値に設定する関数をアセンブリで作成しようとしていますが、スタックから3番目の引数を取得するときに(fastcall呼び出し規約を使用します)レジスタECXは、何らかの歪んだ値を取得します。__fastcallでESPが壊れないようにするにはどうすればよいですか?
インラインアセンブリを使用してVisual Studioにコードを挿入すると、関数が呼び出されたときにESPが大幅に変更されていることがわかります。 最初の2つの引数は何の問題もなくECXとEDXに入れられていますが、問題を引き起こしているのは3番目の引数だけです。
私はVSでデバッグ中にレジスタに値を手動で設定すると、メモリブロックが正しい値で満たされていることが分かります。
私はアセンブリが比較的新しいので、私のコードはおそらく少しばかげていますが、誰もこの問題を解決する方法を知っていますか?
コードは以下の通りです:
#ifdef __GNUC__
#define __fastcall __attribute__((fastcall)) // 'Cause I'm a M$ fanboy
#endif
void __fastcall memset(void *pDest, int iValue, int iSize)
{
__asm
{
; Assume the pointer to the memory is stored in ECX
; Assume the value is stored in EDX
; Assume the size of the block is stored on the stack
mov eax, esi ; Put ESI somewhere it won't be touched (I think)
mov esi, ecx ; Move the address of the memory into ESI
xor ecx, ecx ; Zero ECX
pop ecx ; Get the size of the block into ECX. ECX is our loop counter
memset_count:
cmp ecx, 0 ; If we are at the end of the block,
jz memset_return ; Jump to return
mov [esi], edx ; Move our value into the memory
inc esi ; Otherwise, increment out position in the memory
dec ecx ; Decrement out counter
jmp memset_count ; Start again
memset_return:
mov esi, eax ; Restore ESI
add esp, 4 ; Remove our third argument from the stack
ret
}
}
#define ret return
int main(int argc, char **argv)
{
char szText[3];
/*
__asm
{
push 3
mov edx, 65
lea ecx, szText2
call memset
}
*/
memset(&szText, 'A', 3);
ret 42;
}
'#define ret return'?どのように怠惰なことができますか? – Dani
VSで逆アセンブリビューを有効にして、コードから何が生成されるかを確認できます。 –