memset()과 같이 메모리 블록을 지정된 값으로 설정하는 어셈블리에서 함수를 작성하려고합니다.하지만 스택에서 세 번째 인수를 가져올 때 (fastcall 호출 규칙을 사용함) , 레지스터, ECX는 왜곡 된 값을 얻습니다.__fastcall에서 ESP가 손상되는 것을 어떻게 방지합니까?
인라인 어셈블리를 사용하여 Visual Studio에 코드를 삽입하면 함수를 호출 할 때 ESP가 크게 변경된 것으로 나타납니다. 처음 두 인수는 아무런 문제없이 ECX와 EDX에 입력됩니다. 문제의 원인이되는 세 번째 인수입니다.
나는 코드가 올바른 값으로 채워지는 것을 알고 있습니다. 수동으로 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에서 디스 어셈블리 뷰를 활성화하고 코드에서 무엇이 생성되는지 확인할 수 있습니다. –