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

즉,
해당 명령어는 배열의 4번째 요소를 %eax 레지스터에 로드한다.
요소의 크기가 4바이트이므로 3번째 요소의 주소를 계산하기 위해 12(3*4)를 더하고,
배열의 시작 위치에서 4바이트 떨어진 위치의 값(4) 도 추가로 더한다.
이렇게 하면 총 16(12+4) 바이트의 오프셋이 된다
주소 계산 명령어인 leaq src,dst 의 특징 궁금하잖아 ?
? ?
effective address (유효 주소) : 주소 계산으로 결정된 최! 종 주소를 말한다
src 는 address mode expression 으로, 이 표현식이 나타내는 주소를 나타냄요
dst 는 목적지(destination)를 나타내고. 알지? 계산된 주소를 설정함 ~
어디서 ! 사용되냐?
메모리 참조 없이 주소를 계산할 때,
예를 들어서 홈냥 p = &x[i]; 와 같이 배열 인덱싱 연산 번역할 때 ..
머 이럴 때 쓴답니다잉
또 ?
형식이 x+ k*y 인 산술식 계산할 때. (여기서 k = 1,2,4,8..)
대부분의 명령어에서는 ?
메모리피연산자는 메모리를 접근한다
긍까 봐바
| assembly | C |
|---|---|
| mov 6(%rbx,%rdi,8),%ax | ax = * (rbx+rdi8 + 6) |
| add 6(%rbx,%rdi,8),%ax | ax += *(rbx+rdi8+6) |
| xor %ax,6(%rbx,%rdi,8) | *(rbx+rdi8+6)^=ax |
근데
LEA 명령어는 메모리에 접근을 안 해 !!!
| assembly | C |
|---|---|
| lea 6(%rbx,%rdi,8),%rax | rax = 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 을 계산하는 건 보통의 주소 계산이 아니니깐 포인터일지 아닐 지 명확하지 않다 이거야 .