2011-03-25 6 views

답변

1

%ebp 레지스터는 현재 스택 프레임을 가리키며 함수 매개 변수와 로컬 변수가 저장됩니다. 이 코드는 % ebp에서 오프셋 0x4의 값에 액세스하고 있습니다 (이 값은 표시되지 않음).

+0

@ Zimbabao의 대답에 대한 이미지를 정교하게 도울 수 있습니까? – compiler

0

ebp는 기본 포인터입니다. 스택에 저장된 함수 params는 스택의 첫 번째 param을 가리키는 0x4 (% ebp)를 반환합니다.

2

ebp은 프레임 포인터입니다. esp와 함께 ebp는 현재 프로세스의 스택 프레임을 표시합니다.

0x4 (% ebp)는 실제로 반환 주소입니다.이 호출 이후에 반환 할 함수의 주소가됩니다.

이 그림의 스택 프레임을 확인하십시오.

enter image description here

+0

그래서 스택 프레임은 낮은 메모리에서 높은 메모리로 할당됩니까? – compiler

+0

아키텍처에 따라 다릅니다. 높음에서 낮음이 가장 일반적입니다. x86에서 높은 것에서 낮은 것까지. – Zimbabao

+0

하지만 왜 disasembly는 코드가 항상 낮은 상태에서 높은 상태로 실행되는지 보여줍니다. '0x0000000000400498 : \t 푸시 % rbp 0x0000000000400499 : \t mov % rsp, % rbp' – compiler

4

는 함수의 프롤로그를 가정하면 다음과 같습니다

pushl %ebp 
movl %esp, %ebp 
... 

퍼센트의 EBP베이스 포인터를 저장하는 레지스터 것이다 (또한 프레임 포인터라고도 함). 기본 포인터는 현재 스택 프레임이 스택에서 시작하는 곳입니다. x86에서와 마찬가지로 스택은 아래쪽으로 커지고 로컬은 % ebp에서 음수 오프셋으로 참조됩니다. 매개 변수와 반환 주소는 % ebp의 양의 오프셋에 의해 참조됩니다. % ebp의 값은 스택의 호출자의 % ebp 값 (프롤로그에 의해 푸시 되었음)을 가리 킵니다. 이것은 효과적으로 스택을 "걷는"데 사용할 수있는 기본 포인터의 연결된 목록을 형성합니다. 주 : 이것은 각 스택 프레임에 기본 포인터가 있다고 가정합니다. 다른 용도로 % ebp를 비우는 FPO (Frame Pointer Omission)라고하는 최적화가 있습니다.

그래서 프롤로그가있는 함수가 있고 호출 명령어 (예 : 호출자의 리턴 주소가 스택에 푸시 되었음)로 호출 된 경우 0x4 (% ebp)는 마지막 주소이므로 리턴 주소를 저장합니다 피 호출자의 프롤로그가 실행되기 전에 스택에 푸시됩니다. 따라서 호출 후 다음 명령어 대신 호출자의 호출 명령어 끝에서부터 15 바이트가 반환 된 후에 코드 스 니펫이 실행되어 다음 명령어가 실행됩니다.

편집 : 내 수많은 편집은 지금까지 내 대답을 더 잘 설명해 왔습니다.

+0

+1은 완벽하게 이해할 수 있지만 코드가 매우 부서지기 쉽습니다. – Martin

+0

@Martin : 실제로 호출자에 대한 가정을하는 것처럼 보일 것입니다. 물론 전체 코드가 없으면 우리는 실제로 일어나고있는 일에 대해서만 추측 할 수 있습니다. –

관련 문제