__asm__ __volatile__ (
"movl 0x4(%ebp), %eax \n"
"addl $15, %eax \n"
"movl %eax, 0x4(%ebp)"
);
나는 %eax
이 반환 값을 저장한다는 것을 알고 있지만, 여기에 %ebp
은 무엇입니까?아래 어셈블리를 이해하는 방법?
__asm__ __volatile__ (
"movl 0x4(%ebp), %eax \n"
"addl $15, %eax \n"
"movl %eax, 0x4(%ebp)"
);
나는 %eax
이 반환 값을 저장한다는 것을 알고 있지만, 여기에 %ebp
은 무엇입니까?아래 어셈블리를 이해하는 방법?
%ebp
레지스터는 현재 스택 프레임을 가리키며 함수 매개 변수와 로컬 변수가 저장됩니다. 이 코드는 % ebp에서 오프셋 0x4의 값에 액세스하고 있습니다 (이 값은 표시되지 않음).
ebp는 기본 포인터입니다. 스택에 저장된 함수 params는 스택의 첫 번째 param을 가리키는 0x4 (% ebp)를 반환합니다.
ebp
은 프레임 포인터입니다. esp와 함께 ebp는 현재 프로세스의 스택 프레임을 표시합니다.
0x4 (% ebp)는 실제로 반환 주소입니다.이 호출 이후에 반환 할 함수의 주소가됩니다.
이 그림의 스택 프레임을 확인하십시오.
는 함수의 프롤로그를 가정하면 다음과 같습니다
pushl %ebp
movl %esp, %ebp
...
퍼센트의 EBP베이스 포인터를 저장하는 레지스터 것이다 (또한 프레임 포인터라고도 함). 기본 포인터는 현재 스택 프레임이 스택에서 시작하는 곳입니다. x86에서와 마찬가지로 스택은 아래쪽으로 커지고 로컬은 % ebp에서 음수 오프셋으로 참조됩니다. 매개 변수와 반환 주소는 % ebp의 양의 오프셋에 의해 참조됩니다. % ebp의 값은 스택의 호출자의 % ebp 값 (프롤로그에 의해 푸시 되었음)을 가리 킵니다. 이것은 효과적으로 스택을 "걷는"데 사용할 수있는 기본 포인터의 연결된 목록을 형성합니다. 주 : 이것은 각 스택 프레임에 기본 포인터가 있다고 가정합니다. 다른 용도로 % ebp를 비우는 FPO (Frame Pointer Omission)라고하는 최적화가 있습니다.
그래서 프롤로그가있는 함수가 있고 호출 명령어 (예 : 호출자의 리턴 주소가 스택에 푸시 되었음)로 호출 된 경우 0x4 (% ebp)는 마지막 주소이므로 리턴 주소를 저장합니다 피 호출자의 프롤로그가 실행되기 전에 스택에 푸시됩니다. 따라서 호출 후 다음 명령어 대신 호출자의 호출 명령어 끝에서부터 15 바이트가 반환 된 후에 코드 스 니펫이 실행되어 다음 명령어가 실행됩니다.
편집 : 내 수많은 편집은 지금까지 내 대답을 더 잘 설명해 왔습니다.
+1은 완벽하게 이해할 수 있지만 코드가 매우 부서지기 쉽습니다. – Martin
@Martin : 실제로 호출자에 대한 가정을하는 것처럼 보일 것입니다. 물론 전체 코드가 없으면 우리는 실제로 일어나고있는 일에 대해서만 추측 할 수 있습니다. –
@ Zimbabao의 대답에 대한 이미지를 정교하게 도울 수 있습니까? – compiler