IT이야기

x86_64 어셈블러에서 RBP 레지스터의 목적은 무엇입니까?

cyworld 2022. 5. 28. 10:13
반응형

x86_64 어셈블러에서 RBP 레지스터의 목적은 무엇입니까?

그래서 저는 조립을 조금 배우려고 합니다. 컴퓨터 아키텍처 수업에 필요하기 때문입니다.피보나치 시퀀스를 인쇄하는 등의 프로그램을 몇 개 작성했습니다.

함수를 쓸 때마다 그 세 줄을 사용한다는 것을 알게 되었습니다(어셈블리 코드를 비교함으로써 알게 되었습니다).gcc그것까지C동등) :

pushq   %rbp
movq    %rsp, %rbp
subq    $16, %rsp

이에 대해 두 가지 질문이 있습니다.

  1. 우선, 내가 왜 이 파일을%rbp사용법이 더 심플하지 않나요?%rsp그 내용이 로 이동함에 따라%rbp두 번째 줄에?
  2. 왜 나는 뺄셈을 해야 하는가?%rsp항상 그렇지는 않아요.16제가 어렸을 때printf7개 또는 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-pointerGCC의 경우 기능 구현은 기본적으로 다음과 같이 변경됩니다.

        subq    $8, %rsp    ; Re-align stack frame, and
                            ; reserve memory for local variables

        ; ... function ...

        addq    $8, %rsp
        ret

스택 프레임이 없기 때문에(%rbp는 다른 목적으로 사용되며 그 값은 스택에 푸시되지 않습니다).각 함수 콜은 반환 주소만 스택에 푸시합니다.이것은 8바이트의 양입니다.따라서 8을 빼야 합니다.%rsp16의 배수를 유지하도록 한다.(일반적으로 에서 빼서 더하는 값)%rsp는 8의 홀수 배수입니다).

함수 파라미터는 일반적으로 레지스터로 전달됩니다.상세한 것에 대하여는, 이 회답의 선두에 있는 ABI링크를 참조해 주세요.단, 적분 타입과 포인터는 레지스터로 전달됩니다.%rdi,%rsi,%rdx,%rcx,%r8,그리고.%r9(에 부동소수점 인수를 포함)%xmm0로.%xmm7레지스터를 클릭합니다.

경우에 따라서는rep ret대신rep헷갈리지 마세요.rep ret와 완전히 같은 것을 의미한다ret; 그repprefix는 보통 문자열 명령(예: 명령어)과 함께 사용되지만 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

반응형