공부/JUN STUDY

MOV와 LEA 어셈블리어 차이 그리고 []의 의미 (RAX와 [RAX]의 차이)

JUNFUTURE 2022. 3. 30. 23:36

결론부터 이야기하면

 

mov는 값을 옮기는 어셈블리어

lea는 주소를 옮기는 어셈블리어

rax는 rax에 담긴 값

[rax]는 rax에 담긴 값을 주소로 보겠다. 라는 뜻이다.

 

아래 표를 완벽하게 이해하면 최고다.

1. mov rdi, rsi : rsi에 있는 값을 주소가 아니라 값으로 보고, rdi 레지스터에 값을 넣는다.

2. mov QWORD PTR[rdi], rsi : rsi에 있는 값을 주소가 아니라 값으로 보고, rdi 레지스터에 담겨있는 값을 주소로 보고, 해당 주소에 rsi에 담긴 값을 넣는다.

3. mov QWORD PTR[rdi+8*rcx], rsi : rsi에 있는 값을 주소가 아니라 값으로 보고, rdi값+8*rcx값을 주소로 보고, 해당 주소에 rsi에 담긴 값을 넣는다.

 

[ ]의 의미에 대해

여기서 기억해두면 좋을게,

[ ]가 있든 없든 그 값은 똑같다.

 

그러니까 예를들어 eax값이 0x12345678 일때,

eax = 0x12345678

[eax] = 0x12345678

이다.

 

다만 달라질때는

1. mov eax, 1

2. mov [eax], 1

과 같이 쓰일때 인데,

 

1의 경우 eax 레지스터안에 1을 넣겠다는거고

2의 경우 eax 레지스터가 가리키고 있는 주소에 1을 넣겠다는거다.

 

[ ]는 그 자체로는 의미가 없지만, 명령어의 operand로 사용될때 그 의미가 달라진다.

그래서 1은 eax에 1이 들어가고 2는 0x12345678 주소에 1 값이 들어간다. eax의 값은 여전히 0x12345678이다.

 

MOV와 LEA의 차이

결론부터 이야기하면

 

MOV는 [ ]가 있으면 그 주소에 있는 값을 옮기고

LEA는 [ ]가 있으면 그 주소 값 자체를 옮긴다.

 

MOV랑 LEA를 이해할때 [ ] 가 붙어있는 경우 어떻게 이해하면 좋지??라고 생각하고 접근하면 이해가 수월하다.

MOV는 값을, LEA는 주소를 옮긴다고 생각하면 이해하기 어려운 이유가

사실 주소도 그냥 값으로 표현되어서 그렇다. 앞서 언급했듯 레지스터 이름 혹은 표현식에 [ ] 가 붙든 말든 그 값은 똑같다. 그걸 opcode에 operand 로 사용할때 이걸 어떻게 처리할지에서 차이가 나는건데, 

 

아래 문제를 완벽히 이해하면 좋다.

1. mov rax, [rbx+8]

앞서 살펴보았듯이, 우선 [rbx+8] 값은 0x401A40+0x8 즉, 0x401A48이고

mov 라는 opcode에 operand로 사용됨으로써 0x401A48에 있는 값을 rax에 넣게된다.

rax에는 0x401A48에 있는 값 0xC0FFEE 가 들어가게 된다.

 

2. lea rax, [rbx+8]

역시나 [rbx+8] 값은 0x401A48이고

lea 라는 opcode에 operand로 사용됨으로써 0x401A48이라는 주소 값 자체를 rax에 넣게된다.

rax에는 0x401A48이라는 값이 들어가게된다.