적색 지대의 목적은 무엇입니까?


12

적색 영역은 "할당되지 않은"스택 포인터를 넘어 메모리에서 고정 크기 영역입니다. 컴파일러는 간단한 리프 함수로 해당 영역에 액세스하기 위해 어셈블리를 생성합니다.

그러나 나는 레드 존에 대한 실제 이점을 볼 수 없습니다. 스택 포인터 이외의 메모리에 액세스하면 실제로 위험하며 쉽게 데이터가 손상 될 수 있습니다 . 왜 이렇게합니까? 2 개의 프로세서 명령어 (push ebp; mov ebp esp)를 저장해도 실제 속도는 향상되지 않습니다.

답변:


16

적색 구역은 순수하고 간단하게 지침을 저장할 수있는 최적화입니다. 그것은 더 이상 로컬 스토리지를 만들기 위해 스택 포인터에서 모든 함수에 대해 방출 된 코드를 빼지 않아도됨을 의미합니다.

sub XXX, %rsp 

리프 함수가 아니더라도 모든 함수 호출의 시작 부분에. 종종 컴파일러에서 생성 된 코드는 스택 포인터 아래의 빨간색 영역에있는 임시 공간을 저장하지 않고 다른 함수를 호출하기 전에 사용할 수 있습니다. 이것은 유용한 최적화입니다.

스택 포인터에서 더 이상 서브를 수행 할 필요가없는 경우, 방출 된 코드는 rsp를 기본 포인터로 사용할 수 있고, 일반적으로 rbp를 위해 예약 된 작업이며 방출 된 코드는 rbp를 다른 범용 레지스터로 사용할 수 있습니다.

이것은 궁극적으로 각 함수 호출의 프롤로그와 에필로그가 rbp를 저장하고 복원하는 두 가지 명령을 저장할 수 있음을 의미합니다.

(gnu 어셈블러)

pushq %rbp       # prologue [ two instructions not necessary ]
movq %rsp,%rbp

.... [code]

movq %rbp,%rsp   # epilogue [ two instructions not necessary ]
popq %rbp        

원하지 않는 경우 gcc에서 -mno-red-zone 플래그를 전달할 수 있습니다 (그러나 x86-64 ABI에서는 필요). Linux 커널은 ABI를 준수하지 않아도되므로 모든 커널 코드는 -mno-red-zone으로 컴파일됩니다.

또한 스택 포인터 너머의 메모리에 액세스하는 것이 예상되는 작동 모드 인 경우 위험하지 않습니다. 그것은 위험하며 계획되지 않았을 때 부패로 이어질 수 있습니다. 방출 된 코드가 수행하면 수행중인 작업을 알 수 있습니다.


네, 이해합니다 그러나 1 명령 (esp의 하위)을 저장하는 것이 실제로 최적화입니까? 데이터를 손상시킬 수있는 실제 가격으로 몇 바이트와 1 프로세서 사이클을 절약하는 것은 이상하게 보입니다. 어쩌면 다른 이유가 있습니까?
Alexander Dzyoba

3
정말 최적화입니다 ESP의 하위 아니지만, 더 이상 이후 에이없는 ESP에서 서브, 당신은 기능 코드에 뭔가 다른 기본 포인터 (보통 EBP에 의해 수행) 및 사용 EBP로 ESP 사용할 수 있습니다. 마지막으로 esp는 이제 기본 포인터이므로 코드는 프롤로그 / 에필로그에서 ebp를 저장 및 복원하지 않아도됩니다. 이 추가 정보로 답변을 명확하게하겠습니다
Brian Onn

빨간색 영역은 x86-64 ABI의 일부이므로 편집 및 ebp / esp 대신 rbp / rsp로 변경 (32 비트 레지스터에서 동일한 기술을 사용하는 것을 막을 수는 없지만 오늘날 컴파일러는 그렇게하지 않습니다)
Brian Onn

1
프레임 포인터 생략은 빨간색 영역과 전혀 관련이 없습니다. 컴파일러는 %rsp기본 포인터를 사용하여 스택을 인덱싱 할 수 있습니다 .
alecov
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.