MOV와 LEA 어셈블리어 차이 그리고 []의 의미 (RAX와 [RAX]의 차이)
결론부터 이야기하면
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이라는 값이 들어가게된다.