2011-10-17 2 views
1

스택을 요약하는 보고서를 작성하고 있습니다. 내 프로필을 클릭하면 잠시 동안이 작업을 수행 한 것을 볼 수 있습니다. 지금은 GDB에서 Visual Studio와는 다른 것을 보여주기 때문에 약간의 문제가 있습니다.기본 포인터 및 스택 포인터에 관한 질문

결과적으로 기본 포인터와 스택 포인터에 대한 나의 이해가 너무 명확하지 않아서 잘못된 방향으로 누군가 나를 올바른 방향으로 이끌 수 있기를 바라고 있습니다.

x86 컴퓨터의 경우 스택은 일반적으로 아래쪽으로 커집니다 (높은 메모리 주소에서 낮은 값으로).

그래서 프로그램이 시작될 때 main 함수를 호출했습니다. 일반적으로

  1. , 각 함수 호출의 항목에서, 스택은 현재 ESP 위치에 생성하고, 이것은 우리가 "스택의 맨 위에"라는 것입니다. 이 올바른지?

  2. 이전 ebp가 스택에 푸시되면 esp가 처음으로 가리킨 위치로 푸시됩니까?

  3. 그런 다음 esp가 빈 메모리 위치를 가리 키도록 아래로 이동하겠습니까? 맞습니까?

  4. 마지막으로 esp는 항상 변경되어 다음 사용 가능한 메모리 공간을 가리키며 아래로 이동합니다. 그 맞습니까?

  5. esp는 바이트 단위로 이동합니까, 아니면 4 바이트 단위로 이동합니까?

많은 질문이 있습니다. 하지만 시간 내 주셔서 감사합니다!


응답 해 주셔서 감사합니다.

@iSciurus

나는 모두가 스택으로 푸시 된 가장 최근의 항목을 가리키는 ESP 정의하는 방법 혼란 스러워요.

x86의 경우 스택이 아래쪽으로 커지기 때문에 설명에서 esp는 맨 처음 스택의 가장 낮은 주소를 가리 킵니다. 어셈블리 코드를 보면,

0x080483f4 <+0>: push %ebp 
    0x080483f5 <+1>: mov %esp,%ebp 
    0x080483f7 <+3>: sub $0x10,%esp 

그래서 essp가 16 바이트 감소합니다. 따라서 이것은 크기이 함수 호출 스택입니다. 로컬 변수는 반송 주소 바로 뒤에옵니다 (ebp-4, ebp-8 등). esp의 전반적인 목적은 무엇입니까? 내가 이해하는 바로는 스택 오버플로가 그보다 작은 주소에 액세스하려고 할 때 발생합니다.

마지막으로 스택 상단을 말하면 가장 낮은 주소 (x86의 경우)를 나타냅니다.

내가 생각하고있는 사진입니다 이러한 오랜 질문에 대한

[Parameter n   ] 
... 
[Parameter 2   ] 
[Parameter 1   ] 
[Return Address  ] 0x002CF744 
[Previous EBP   ] 0x002CF740 (current ebp) 
[Local Variables  ] 
-- ESP 

죄송합니다 (아래 성장). 하지만 정말 고맙습니다.

답변

1
  1. 올바른 결과를 얻으려면 스택 자체가 아닌 현재 esp 위치에 스택 프레임이 만들어집니다. 스택은 스레드 시작시 한 번 만들어지며 각 스레드는 자체 스택을 가지며 프로세스 메모리 공간의 한 영역에 불과합니다. 스택 프레임은 실제로 각 함수 항목에서 생성되며 스레드 스택 내부의 영역입니다.

  2. 없음, 이는 어드레스 푸시된다 old_esp - 4] (또는 [old_rsp - 8 64)에서, ESP 최저 사용 된 어드레스의 스택 포인트 가기 때문이다. 스택의 다음 DWORD (또는 QWORD)는 비어 있으며 ebp가 거기에 푸시됩니다.

  3. 은 예, 이것은 일반적 ESP 아닌 다음 사용 가능한 공간에서, 스택의 최저 사용 주소를 가리키는 아래로 이동되고,

  4. 호 우선 ESP 부, 값으로 이루어진다. 둘째, esp는 스택뿐만 아니라 어디에서나 가리킬 수 있습니다. push/pop과 같은 스택 관련 instuctions를 사용할 때까지는 괜찮습니다.

  5. 기계마다 ES 문자 이동 : x86에서는 4 바이트 단위로 이동하고 x64에서는 8 바이트 단위로 이동합니다. 스택의 상단을 저장할 수 :


ESP의 전반적인 목적은 거의 항상 동일합니다. pop/push와 같은 모든 스택 관련 명령어는 인수로 esp를 사용합니다. x86에서 ebp와 esp는 모두 스택 프레임 (하단과 상단에 해당)에 대한 정보를 저장하는 데 사용됩니다. 어쩌면, 당신은이 중복에 대해 혼란 스러울 것입니다. 그러나 x64에서는 스택 기반 매개 변수에 rsp 만 사용되고 rbp는 범용 레지스터입니다.

스택에서 버퍼 오버플로는 코드가 배열의 마지막 요소 (또는 구조체 등)보다 더 높은 쓰기를 시도 할 때 자주 발생합니다. 스택은 아래로 자라나 배열은 위쪽으로 자랍니다. 더 높은 값을 쓸 때 우리는 호출자의 내부 변수뿐만 아니라 반송 주소, SEH 처리기에 액세스 할 수 있습니다.

예, 상단이라고 말하면 가장 낮은 주소를 의미합니다. 여기

-- ESP 
[Local Variables  ] 
[Previous EBP   ] 0x002CF740 (current ebp) 
[Return Address  ] 0x002CF744 
[Parameter 1   ] 
[Parameter 2   ] 
... 
[Parameter n   ] 

은, ESP 모든 데이터 "위의"값을 가리키는과 더 "정상"과 같은 : 그래서, 대부분의 디버거는 역순으로 스택을 보여줍니다. 그것은 여전히 ​​가장 낮은 사용 주소입니다.

+0

감사합니다. 나는 여전히 약간의 의문이 있으며 나는 나의 글을 편집했다. 시간이 있다면 좀 봐도 될까요? 감사. – CppLearner

+0

고맙습니다. 마지막으로 알고 싶은 것은 로컬 변수 아래에는 "동적 메모리"라고 불리는 영역이 있습니다.이 영역은 아직 처리되지 않았습니다 (잘하면). 그래서 이것은 우리가 "스택을 원하는대로 성장"시키는 과정입니다. 프로세스 내에서 "새"연산자라고 부릅니다. 이제 새로운 스토리지가 ESP 아래에 생성됩니다. ESP가 지금 아래로 움직입니까? 감사. – CppLearner

+0

아니요, esp는 힙과 공통점이 없으므로 변경되지 않습니다. – asd