2014-10-01 8 views
1

저는 지금 당분간 어셈블리를 연구 해왔고 그걸 이해하기 시작했습니다. 그러나 이해할 수없는 한 가지 이 작은 프로그램 (& T 구문 AT, 64 비트 GNU 컴파일러로 컴파일 된 코드를)함수를 호출 할 때 스택 포인터를 감소시킬 필요가있는 이유는 무엇입니까?

pushq %rbp 

movq %rsp, %rbp 

subq $48, %rsp 

call __main 
movl $0, -4(%rbp) 
movl $4, -8(%rbp) 
movl -8(%rbp), %edx 
movl -4(%rbp), %eax 
addl %edx, %eax 
movl %eax, -12(%rbp) 
movl -4(%rbp), %edx 
movl -12(%rbp), %eax 
addl %eax, %edx 
movl -8(%rbp), %eax 
addl %edx, %eax 
movl %eax, -16(%rbp) 
addq $48, %rsp 
popq %rbp 
ret 

을 : 우리는이 코드를 살펴 로컬 변수에 대한 로밍을 떠날 스택 포인터를 감소시키는 데 필요한 않는 이유입니다 나는 그 모든 것을 esp를 48만큼 줄이지 않고도 할 수 있다고 상상할 수있다. 나는 base pointer를 사용하여 stack과 값을 이동시키고, esp가 ebp를 pop하고 반환 할 준비가되어있는 같은 위치를 가리킬 수있다. 누군가 지역 변수에 "방"을 남겨 둘 필요가있는 이유를 분명히 할 수 있습니다. 감사합니다. !! 어리석은 질문 인 것 같으면 사과드립니다

답변

2

함수 호출시 사용하는 모든 함수에 스택에 변수를 배치 한 위치에 대해 자세히 알고 싶습니까? 기능

많은 다른 함수를 호출 - 스택 포인터를 감소시키는 것은 함수 "나는 스택의이 비트를 사용하고 있습니다"라고 할 수있는 길입니다


"잎"방법 - 결코 호출하지 방법 다른 함수는 실제로 여러분이 제안한 스타일로 작성 될 수 있습니다. 왜냐하면 다른 코드가 스택을 자체적으로 사용하지 않기 때문입니다.

+0

좋아요, 스택 포인터를 감소시키는 요령은, 우리가 다른 함수를 호출 할 때'mov "return address", -52 ($ ebp)'와 같은 일을하는 번거 로움을 덜어주기위한 것입니다. 항상 ebp를 줄입니다. 우리는 새로운 함수에 대한 지역 변수를 삽입하고, alsp는 각 프레임의 beginig와 end를 추적합니다 (ebp를 밀고 esp를 줄임으로써). – user3769877

-2

함수를 기억하는 데 사용되며 재귀 함수 호출에 매우 유용합니다.

+2

더 이상 애매하거나 불완전 할 수 없습니다. –

0

스택 포인터에서 상수를 뺀 것은 로컬 변수에 공간을 할당하는 방법입니다. 컴파일러 또는 어셈블러 프로그래머는 이러한 변수가 rbp의 음수 오프셋 또는 rsp의 양수 (또는 0) 오프셋 중 어디에 위치하는지 알 수 있습니다.

몇 가지 추가 작업을 수행하고 결과를 스택의 로컬 변수 데이터에 저장 한 다음 스택 포인터에 상수를 다시 추가하여 효과적으로 모든 로컬 변수를 해제합니다 eax에 합계를 남겨 둡니다.) 또한이 예제를 보면 "가장 낮은"주소는 rbp-16에서 4 바이트의 데이터이므로 esp에서 20을 뺀 값이면 충분합니다 (이 경우).

_alloca()와 같은 것이 사용되면 스택에서 다양한 양의 메모리를 할당하므로 더 복잡해질 수 있습니다.

또한 rbp는 선택 사항입니다. 예제 코드에서 "프레임 포인터"로 사용되지만 일부 컴파일러에서는 프레임 포인터를 사용하지 않도록 설정할 수 있습니다.이 경우 컴파일러는 rsp (또는 32 비트 모드 인 경우 esp) 만 사용하여 로컬 변수를 추적하고 up rbp (또는 ebp)를 제네릭 레지스터로 사용합니다.

2

인터럽트가 발생하면 RSP보다 작은 주소의 모든 것이 공정한 게임입니다. 운영 체제는 묻지 않고 해당 데이터를 지워 버립니다 (즉, 자체 데이터로 바꿉니다). 인터럽트는 항상 발생합니다. Ergo - 당신은 RSP 이하에서 당신이 관심있는 모든 것을 지켜야합니다.

또한 다른 함수를 호출하면 반환 주소가 푸시됩니다. RSP 위에 빈 공간이 없으면 데이터를 덮어 씁니다.