x86_64 어셈블러에서 RBP 레지스터의 목적은 무엇입니까?
그래서 저는 조립을 조금 배우려고 합니다. 컴퓨터 아키텍처 수업에 필요하기 때문입니다.피보나치 시퀀스를 인쇄하는 등의 프로그램을 몇 개 작성했습니다.
함수를 쓸 때마다 그 세 줄을 사용한다는 것을 알게 되었습니다(어셈블리 코드를 비교함으로써 알게 되었습니다).gcc
그것까지C
동등) :
pushq %rbp
movq %rsp, %rbp
subq $16, %rsp
이에 대해 두 가지 질문이 있습니다.
- 우선, 내가 왜 이 파일을
%rbp
사용법이 더 심플하지 않나요?%rsp
그 내용이 로 이동함에 따라%rbp
두 번째 줄에? - 왜 나는 뺄셈을 해야 하는가?
%rsp
항상 그렇지는 않아요.16
제가 어렸을 때printf
7개 또는 8개의 변수를 입력하면24
또는28
.
Manjaro 64비트를 가상 머신(4GB RAM), 인텔 64비트 프로세서로 사용
rbp
는 x86_64 의 프레임 포인터입니다.생성된 코드에서는 스택포인터 스냅샷이 생성됩니다.rsp
)에 대한 조정이 이루어졌을 때rsp
(즉, 지역 변수를 위한 공간을 확보하거나push
값을 스택에 입력)에서 로컬 변수와 함수 매개변수에 계속 액세스할 수 있습니다.rbp
.
많은 컴파일러가 최적화 옵션으로서 프레임 포인터 생략을 제공합니다.이것에 의해, 생성된 어셈블리 코드의 액세스 변수가,rsp
대신 자유롭게rbp
기능에 사용하기 위한 또 다른 범용 레지스터로 사용됩니다.
AT&T 어셈블러 구문에서 사용하는 GCC의 경우 스위치는-fomit-frame-pointer
. 해당 스위치로 코드를 컴파일하여 어떤 어셈블리 코드를 얻을 수 있는지 확인합니다.아마 에 대한 상대적인 값에 액세스 할 수 있을 것입니다.rsp
대신rbp
, 포인터로부터의 오프셋은 기능 전체에 걸쳐 다릅니다.
Linux는 x86-64(AMD64)용 System V ABI 아키텍처를 사용합니다.자세한 내용은 OSDev Wiki의 System V ABI를 참조하십시오.
즉, 스택이 다운되는 것을 의미합니다.주소가 작을수록 스택의 「상위」가 됩니다.일반적인 C 함수는 다음과 같이 컴파일됩니다.
pushq %rbp ; Save address of previous stack frame
movq %rsp, %rbp ; Address of current stack frame
subq $16, %rsp ; Reserve 16 bytes for local variables
; ... function ...
movq %rbp, %rsp ; \ equivalent to the
popq %rbp ; / 'leave' instruction
ret
로컬 변수용으로 예약된 메모리의 양은 스택을 16바이트로 정렬하기 위해 항상 16바이트의 배수입니다.로컬 변수에 스택공간이 필요 없는 경우subq $16, %rsp
또는 유사한 지시입니다.
(반환 주소와 이전 주소는%rbp
스택에 푸시된 값은 둘 다 8바이트, 합계 16바이트입니다).
한편, 「 」는, 「 」, 「 」의 사이에%rbp
있습니다.%rsp
스택의 상단을 가리킵니다.는 이 두 가지 있기 입니다.%rbp
★★★★★★★★★★★★★★★★★」%rsp
함수 내의 모든 지점에서 두 변수 중 하나를 로컬 변수의 기준으로 자유롭게 사용할 수 있습니다.
스택 프레임은 로컬 함수의 놀이터일 뿐입니다. 즉, 현재 함수가 사용하는 스택 영역입니다.
의 경우할 수 없기 때문에 를 들어이는 C로 작성된 프로그램의 경우 스택프레임이 디버깅에 가장 유용하지만 그 외에는 그다지 유용하지 않기 때문입니다.(예를 들어 를 사용할 수 있습니다). -O2 -fno-omit-frame-pointer
단, 스택프레임을 유지하면서 최적화를 유효하게 합니다).
같은 ABI가 모든 바이너리에 적용되지만, 어떤 언어로 쓰여져 있든 간에, 특정 다른 언어에서는 스택 프레임을 언와인드(예를 들어 현재 함수의 상위 호출자에 대한 예외 설정)를 위해 스택 프레임이 필요합니다.즉, 하나 이상의 함수가 중단되어 일부 상위 펑트에 전달될 수 있는 스택 프레임을 언와인드(unwind)합니다.불필요한 것을 스택에 남기지 않고, 이온을 사용합니다.
스택 프레임이 생략된 경우 ---fomit-frame-pointer
GCC의 경우 기능 구현은 기본적으로 다음과 같이 변경됩니다.
subq $8, %rsp ; Re-align stack frame, and
; reserve memory for local variables
; ... function ...
addq $8, %rsp
ret
스택 프레임이 없기 때문에(%rbp
는 다른 목적으로 사용되며 그 값은 스택에 푸시되지 않습니다).각 함수 콜은 반환 주소만 스택에 푸시합니다.이것은 8바이트의 양입니다.따라서 8을 빼야 합니다.%rsp
16의 배수를 유지하도록 한다.(일반적으로 에서 빼서 더하는 값)%rsp
는 8의 홀수 배수입니다).
함수 파라미터는 일반적으로 레지스터로 전달됩니다.상세한 것에 대하여는, 이 회답의 선두에 있는 ABI링크를 참조해 주세요.단, 적분 타입과 포인터는 레지스터로 전달됩니다.%rdi
,%rsi
,%rdx
,%rcx
,%r8
,그리고.%r9
(에 부동소수점 인수를 포함)%xmm0
로.%xmm7
레지스터를 클릭합니다.
경우에 따라서는rep ret
대신rep
헷갈리지 마세요.rep ret
와 완전히 같은 것을 의미한다ret
; 그rep
prefix는 보통 문자열 명령(예: 명령어)과 함께 사용되지만 prefix가 prefix에 적용되었을 때는 아무것도 하지 않습니다.ret
설명.다만 일부 AMD 프로세서의 브랜치 프레딕터는 이 프로세서에 대해ret
권장되는 회피책은, 다음의 명령어를 사용하는 것입니다.rep ret
대신 거기.
마지막으로 스택 상단의 빨간색 영역(주소가 128바이트 미만)을 생략했습니다.%rsp
이는 일반적인 기능에는 그다지 도움이 되지 않기 때문입니다.일반적인 have-stack-frame의 경우 디버깅을 가능하게 하기 위해 로컬 데이터를 스택프레임 내에 넣어야 합니다.optit-stack-frame의 경우 스택 얼라인먼트의 요건은 이미 8을 빼야 한다는 것을 의미합니다.%rsp
뺄셈에 로컬 변수에 필요한 메모리를 포함하면 비용이 들지 않습니다.
언급URL : https://stackoverflow.com/questions/41912684/what-is-the-purpose-of-the-rbp-register-in-x86-64-assembler
'IT이야기' 카테고리의 다른 글
vuex의 저장 상태가 localStorage에 저장되지 않는 이유는 무엇입니까? (0) | 2022.05.28 |
---|---|
Optional.of.OfNullable보다 Optional.of를 사용하는 이유 (0) | 2022.05.28 |
스프링 부트 명령줄에서 활성 프로파일 및 구성 위치 설정 (0) | 2022.05.28 |
vuejs spa 및 laravel api 구글 사인인 (0) | 2022.05.28 |
도우미 기능에서 Vuex 스토어에 액세스하는 방법 (0) | 2022.05.28 |