x86-64 어셈블리 기본 명령어 정리
어셈블리 공부를 시작하며 자주 보게 되는 x86-64 Intel 문법 기준 기본 명령어를 데이터 이동, 산술 연산, 비트 연산, 비교와 분기, 함수 호출 규약 중심으로 정리했습니다
개요
어셈블리 언어 공부를 시작하면서, 먼저 자주 보게 되는 기본 명령어를 정리해 두려고 한다.
이 글은 다음 기준으로 작성했다.
아키텍처: x86-64 문법: Intel syntax 호출 규약: Linux System V AMD64 ABI
IDA, Ghidra, 디버거, 익스플로잇 라이트업을 보다 보면 아래 명령어들은 거의 계속 나온다. 처음부터 모든 명령어를 외우기보다는, “이 명령어가 값을 옮기는지, 계산하는지, 비교하는지, 흐름을 바꾸는지” 정도로 묶어서 보는 편이 이해하기 좋다.
데이터 이동
가장 먼저 볼 명령어는 mov 다. 이름 그대로 값을 옮긴다. 다만 실제로는 “복사”에 가깝다. 원본 레지스터나 메모리 값이 사라지는 것은 아니다.
mov rax, rbx ; rbx 값을 rax에 복사 mov rax, 0x10 ; rax에 즉시값 0x10 저장 mov rax, [rbp-8] ; rbp-8 주소의 메모리 값을 rax에 로드 mov [rbp-8], rax ; rax 값을 rbp-8 주소에 저장
대괄호 [] 가 붙으면 그 안의 값을 “주소”로 해석한다.
mov rax, [rbp-8]
위 코드는 rbp-8 이라는 주소에 들어 있는 값을 rax 로 가져온다.
반대로 lea 는 메모리에 접근하지 않고 주소값 자체를 계산한다.
lea rax, [rbp-8] ; rbp-8 주소값 자체를 rax에 저장
처음 볼 때는 mov rax, [rbp-8] 와 lea rax, [rbp-8] 가 헷갈린다.
mov rax, [rbp-8] -> rbp-8 주소에 있는 값을 가져옴 lea rax, [rbp-8] -> rbp-8이라는 주소값 자체를 가져옴
스택을 다룰 때는 push , pop 을 자주 본다.
push rax ; rax를 스택에 저장, rsp -= 8 pop rax ; 스택 top을 rax에 저장, rsp += 8
x86-64에서 일반적인 push rax 는 8바이트를 스택에 저장하고, rsp 를 8만큼 감소시킨다. 스택은 낮은 주소 방향으로 자란다는 점도 같이 기억해 두면 좋다.
레지스터끼리 값을 교환할 때는 xchg 를 사용할 수 있다.
xchg rax, rbx ; rax와 rbx 값 교환
산술 연산
기본적인 덧셈과 뺄셈은 add , sub 로 한다.
add rax, rbx ; rax = rax + rbx sub rax, rbx ; rax = rax - rbx
곱셈과 나눗셈은 부호가 있는지 여부에 따라 명령어가 나뉜다.
댓글