2010-03-12 2 views
3

저는 약간의 어셈블리를 배우는 초보자입니다. 함수 호출 전에 ESP 레지스터를 유지하면 더하거나 뺄 때 중요합니다. 설명하기 어려운, 다음 사항을 고려함수 호출 후에 esp를 보존하는 초보자 학습 어셈블리

mov esi, esp 
sub esp, 12 // on 32bit OS this would mean that there are 3 arguments to the function 
// push, function call etc 
cmp esi, esp // should be the same 

또는

mov esi, esp 
// push, function call etc 
add esp, 12 
cmp esi, esp // should be the same 

또한, CMP가 실패 어떤 이유로, 그것은 스택을 다시 정렬, ESP ESI를 MOV 할 안전한지?

감사

편집

: 또한 내가 어떻게 sprintf와 같은 호출에 대해이 작업을 수행 할 필요가 오지만, 메시지 박스 나를 위해 ESP를 해결하는 것? 어떤 기능이 필요하고 어떤 기능이 필요하지 않은지 어떻게 알 수 있습니까?

답변

4

예, esp를 사용할 때 올바른 기호를 얻는 것이 중요합니다 (이 경우 빼기, 함수의 인수처럼 스택에 이미있는 것을 참조 할 때 추가해야 할 때도 있음). 그 이유는 스택이 메모리에서 의 아래쪽에있는으로 증가하기 때문입니다. 이것은 우리가 보통 스택을 생각하는 것과는 상반되는 것입니다 (당신이 맨 위에 놓고 맨 위에서 그것을 제거합니다). 메모리에서 stac k가 커지면 더 높고 높은 주소가됩니다. 그러나 X86 (및 대부분의 다른) 프로세서의 호출 스택은 실제로 아래쪽으로 커집니다. 이는 스택 맨 아래에 플레이트를 추가하고 맨 아래에서 플레이트를 제거하는 것과 같습니다. 메모리에서 스택에 더 많은 것들이 추가 될수록 주소는 점점 낮아집니다.

예, 값을 esp로 변경하는 것이 안전합니다. 설정하려는 항목이 스택 내부의 유효한 위치이고 어떤 것이 필요하지 않은 것이 확실한 한 그렇게하면 잃는 정보의 이 경우 정확히 같은 이유로 esi에 esp를 저장하고 있습니다 ... esi에서 esp를 복원 할 수 있으므로 이전 함수 호출이 무엇이든 관계없이 esp는 원하는 위치에 있습니다.

sprint와 MessageBox의 차이점은 "호출 규칙"입니다. 이것은 상위 레벨 언어 (C)에게 스택 프레임을 처리하는 방법과 호출 될 때 등록하는 방법을 알려줍니다. sprintf는 cdecl이고 MessageBox는 stdcall입니다.

+0

매우 유익한 감사합니다. – Daniel

1

또한 sprintf와 같은 호출에 대해이 작업을 수행해야하지만 MessageBox가 나를 위해 ESP를 수정하는 것처럼 보입니까?

이것은 MessageBox() 함수가 반환 할 때 스택에서 매개 변수를 지우는 때문입니다. 매개 변수 수가 고정되어 있기 때문에이 작업을 수행 할 수 있습니다.

그러나 가변 수의 매개 변수로 sprintf() 함수가 호출됩니다. 이 함수는 호출자가 스택에 푸시 한 수를 알지 못하므로 호출이 반환 될 때 호출자가 호출을 정리해야합니다.

+0

아, 그 말이 맞습니다. 입력 해 주셔서 감사합니다. – Daniel