-
[디스어셈블리 코드] 간단한 메서드 호출과 동작을 해석해보자개발/C·C++ 2024. 7. 13. 13:52
다음과 같은 코드가 있다.
#include <iostream> class MyData { public: void setData(int data) { this->data = data; } private: int data = 0; }; int main() { MyData a; a.setData(10); }
setData 메서드 호출 직전에 디스어셈블리 코드에서는 다음과 같은 작업을 확인할 수 있다
MyData a; 00007FF605341A2D lea rcx,[a] 00007FF605341A31 call MyData::MyData (07FF60534120Dh) a.setData(10); 00007FF605341A36 mov edx,0Ah 00007FF605341A3B lea rcx,[a] 00007FF605341A3F call MyData::setData (07FF605341131h)
1. 64비트 환경에서 함수의 인수는 먼저 메모리에 저장된다. 0A는 16진수로 10이고 이 값이 edx라는 레지스터에 저장한다.
2. 객체 a의 주소를 rcx 레지스터에 저장한다
3. MyData::setData를 호출한다
다음부터는 코드에 주석을 달았다
void setData(int data) { // rsp 스택 포인터 레지스터 // 인수로 받은 10이 저장된 edx를, 객체의 주소가 저장된 곳의 // 다음 위치인 rsp+10에 저장한다 00007FF605341990 mov dword ptr [rsp+10h],edx // rcx에 저장된 객체의 주소를 rsp+8 위치에 저장 00007FF605341994 mov qword ptr [rsp+8],rcx // 반드시 this 명기 this->data = data; // 위에서 rsp+8에 this라는 레이블이 붙음 00007FF6053419B3 mov rax,qword ptr [this] // 위에서 rsp+10에 data라는 레이블이 붙음 00007FF6053419BA mov ecx,dword ptr [data] 00007FF6053419C0 mov dword ptr [rax],ecx
포인트는 this, data를 C++에서 작성한 변수 그대로 받아들이면 안 된다. rcx에 저장되어 있던 객체의 주소를 rsp+8 위치에 저장하고 있는데, 이 rsp + 8의 주소가 this로 레이블된 거고, rsp+10h이라는 주소가 data로 레이블링된 거다.
[data]의 의미는 [rsp+10h]와 똑같고 [] 연산자를 통해 해당 메모리가 역참조 하고 있는 값을 가져온다. 그러므로 ecx에는 10이 저장된다. mov rax, qword ptr [this]에서 this는 rsp+8과 같기 때문에 이 주소를 역참조하면 객체의 주소를 얻고 이를 rax에 저장한다. [this] 앞에 qword ptr이 붙는 이유는 this가 역참조하고 있는 값이 8바이트이기 때문이고, [data]앞에 dword ptr이 붙는 이유는 4바이트이기 때문이다.
디스어셈블리 코드에서 this, data는 변수처럼 보이지만 인간이 코드 해석을 쉽게 할 수 있도록 레이블링한 것이지 실제 변수와 동일하게 생각하면 안 된다.
'개발 > C·C++' 카테고리의 다른 글
전화번호 무작위 생성 (0) 2024.08.03 [정렬] 더미 노드와 병합 정렬 (0) 2024.07.18 메모리 정렬, 패딩 그리고 비트필드(feat. 구조체) (0) 2024.07.07 문자열 파싱 연습하기(feat. strtok_s) (0) 2024.07.04 전역변수의 반환 (0) 2022.01.09