int x = 5;
void foo()
{
long unsigned r[8];
memset(&r, 0, sizeof(long unsigned) * 8);
__asm {
pushad;
pop r[7];
pop r[6];
pop r[5];
pop r[4];
pop r[3];
pop r[2];
pop r[1];
pop r[0];
}
printf("Register values: \n");
printf("eax: %lu\n", r[0]);
printf("ecx: %lu\n", r[1]);
printf("edx: %lu\n", r[2]);
printf("ebx: %lu\n", r[3]);
printf("esp: %lu\n", r[4]);
printf("ebp: %lu\n", r[5]);
printf("esi: %lu\n", r[6]);
printf("edi: %lu\n", r[7]);
if (--x) { foo(); }
}
int main()
{
foo();
return 0;
}
방금 누름/푸시 동작에 대해 배웠고 GPR이 어떻게 변경되는지 확인하려고합니다. 그러나 각 foo() 호출 44에 의해 내림차순으로 번호를 인쇄하는 r [0] 제외한 모든 이들에 대해 0 인쇄물을 받고있는 것 같습니다. 그 맞습니까?재귀 함수에서 누름 단추를 사용할 때 스택 포인터가 증가하지 않는 것 같음
내가 알기로는 새로운 기능을 호출 할 때마다 esp 레지스터가 움직이지 않아야합니까?
일반적으로 'pushad' /'popad'를 사용하지 마십시오. 그들은 느리고 거의 모든 레지스터를 저장/복원 할 필요가 거의 없습니다. (일반적으로 함수는 eax/ecx/edx를 망칠 수 있습니다). 또한 MSVC 스타일의 인라인 asm에서는 레지스터를 직접 저장/복원 할 필요가 없습니다. 컴파일러는 저장이 필요할 경우 사용하는 레지스터를 저장합니다. (코드가 이미'ebx','esi' 등을 저장 한 더 큰 함수로 인라인 되었다면) –
@PeterCordes 아, 알겠습니다. 우리가 제공 한 사용자 수준의 스레딩 과제는 pushad와 popad (esp, ebp 및 eip 이외의 레지스터는 거의 알지 못함) 만 다루었 기 때문에 대부분의 사람들이이 작업을 수행하고 있습니다. – ozma