데이터연산_2 :Leaq

·2024년 4월 20일

컴퓨터 구조

목록 보기
9/11

Leaq에 대해 좀 더 알아보자공 ~🤍

인덱스 레지스터와 displacement 가 함!께? 사용될 때.. 를 봐보자

  • %rbx 레지스터에는 mystruct 인스턴스의 기본 주소가 포함되어 있다
  • %rcx 레지스터에는 인덱스 값인 3이 포함되어 있다
  • movl 4(%rbx,%rcx,4), %eax
    - rbx를 기본주소로 사용, rcx 의 값에 4를 곲한 결과를 추가하여 메모리 주소를 계산함.
    그 뒤에 4 더해.
    이렇게 계산된 메모리 주소에 위치한 값을 %eax 레지스터에 로드함.

즉,
해당 명령어는 배열의 4번째 요소를 %eax 레지스터에 로드한다.
요소의 크기가 4바이트이므로 3번째 요소의 주소를 계산하기 위해 12(3*4)를 더하고,
배열의 시작 위치에서 4바이트 떨어진 위치의 값(4) 도 추가로 더한다.
이렇게 하면 총 16(12+4) 바이트의 오프셋이 된다

address computation instruction (주소 계산 명령어)

주소 계산 명령어인 leaq src,dst 의 특징 궁금하잖아 ?
? ?

  • effective address (유효 주소) : 주소 계산으로 결정된 최! 종 주소를 말한다
    src 는 address mode expression 으로, 이 표현식이 나타내는 주소를 나타냄요
    dst 는 목적지(destination)를 나타내고. 알지? 계산된 주소를 설정함 ~

  • 어디서 ! 사용되냐?

    메모리 참조 없이 주소를 계산할 때,
    예를 들어서 홈냥 p = &x[i]; 와 같이 배열 인덱싱 연산 번역할 때 ..
    머 이럴 때 쓴답니다잉

    또 ?
    형식이 x+ k*y 인 산술식 계산할 때. (여기서 k = 1,2,4,8..)

메모리 피연산자 and LEA

대부분의 명령어에서는 ?
메모리피연산자는 메모리를 접근한다

긍까 봐바

assemblyC
mov 6(%rbx,%rdi,8),%axax = * (rbx+rdi8 + 6)
add 6(%rbx,%rdi,8),%axax += *(rbx+rdi8+6)
xor %ax,6(%rbx,%rdi,8)*(rbx+rdi8+6)^=ax

근데
LEA 명령어는 메모리에 접근을 안 해 !!!

assemblyC
lea 6(%rbx,%rdi,8),%raxrax = rbx+rdi*8 + 6

긍까 lea 원래 주 목적이 뭐였어 메모리 계산 쉽게 해라~ 이거였잖아?

근데 !
일반적 산술연산에도 활용을 한다 이거지....

pointer가 아니라 , 그냥 숫자일 뿐 이다 이거야 위에 봐밥 * 표시가 없잖아

그래서 ... LEA 왜 쓴다고 ??? 🫡❓

(주 목적)🙄
CPU 설계자는 주로 LEA 를 객체나 배열 요소에 대한 포인터를 계산하기 위해 사용하는 것을
의도했다고 ..

이렇게 계산된 포인터는
예를 들어 다른 함수에 하나의 배열 요소를 전달하는데 사용될 수도 있다?

(용도와 다르게도 쓰더라~😜)
그러나 컴파일러 최적화 도구들은 종 종 LEA 를 보통의 산술 연산에 사용하기도 한다 이거야.

LEA 는 복잡한 계산을 한번의 명령어로 수행할 수 있어서 특정 유형의 계산에 효율적이거든.

LEA는 x86 아키텍처에서 사용가능한삼항 명령어 중 하나거든?
또 다른 장점은 LEA가 조건 코드를 변경 안 해 !
그래서 조건 분기에 영향을 안 주고 산술 연산을 수행하기에 아주 적합해

어떤 숫자가 포인터인지 파악하려면 ?

숫자가 메모리 주소로 사용되고 있는지 그렇지 않은지! 를 파악( 문맥 고려하라는 거)
해야 해당 숫자가 포인터인지를 결정 가능

레지스터는 저장되어 있는 값이 주소값인지 ..데이터값인지... signed/unsigned 인지 몰라!

%rsp %rip 는 항상 ~ 포인터를 저장한다.

%rsp는 스택의 맨 위(가장 최근에 푸시된 데이터)를 가리키는 포인터이며, 
%rip는 현재 실행 중인 명령어의 주소를 가리키는 포인터이다. 

이 두 레지스터는 프로그램의 실행 흐름을 제어하는 데 중요한 역할을 한다. 
%rsp는 함수 호출 및 스택 프레임 관리에 사용되고,
%rip는 명령어의 실행 위치를 추적하여 프로그램의 실행 흐름을 조정한다. 
따라서 이러한 레지스터들은 포인터로 사용됩니다.

if ? register 가 포인터로 사용된다면

mov(%rsi),%rsi

복잡한 주소모드의 경우..?

(%rsi, %rbx)
: 둘 중 뭐가 포인터인지 명확하지가 않아

(%rsi, %rbx, 2)
: %rsi 는 포인터이지만? %rbx는 포인터가 아닐 수 도 있엉. 왜냐구 ..?
주소 모드가 포인터를 나타내는 방법에 따라 다르니깐.
rsi + 2rbx 인데.. rsi 는 base address(포인터) 이고 2rbx는 offset.

0x400570(, %rbx, 2)
: 0x400570 는 포인터이지만, %rbx는 포인터가 아닐 수도 있어
rbx 가 offset 에 사용되는 경우이기 때문에 이 값이 포인터일 필요는 없잖아
그칭?
그러니까 모른다 이거야 걍 오프셋을 나타내는데 사용될 뿐이니깐.

lea( 아무 거나 ), %rax-(아무거나)
:포인터일 수 도, 아닐 수도 ~..

lea 명령어에서는 주소를 계산하기 위해서 레지스터랑 상수를 이용하잖어. 그니까 주어진 lea 명령어에서 첫번째 피연산자에 어떤 값이 들어가냐에 따라 결과가 포인터가 될 수도 아닐 수도 ~..

첫번째가 메모리 주소를 나타내는 포인터나 메모리 주소를 계산하는데 이용될 수 있는 값이면 포인터일 수 있지.
근데 만약 첫번째 가 메모리 주소랑 직접적인 연관이 없으면 아닐수도 있다 이말이야

그리고 %rax 에 대한 offset 을 계산하는 건 보통의 주소 계산이 아니니깐 포인터일지 아닐 지 명확하지 않다 이거야 .

profile
어리둥절 빙글빙글 돌아가는 코딩세상~

0개의 댓글