어셈블리어(Assembly language)는 컴퓨터 프로그래밍 언어 중 하나로, 기계어(Machine language)를 기반으로 한 낮은 수준의 프로그래밍 언어이다. 기계어는 0과 1로 이루어져 있어서 사람이 직접 작성하기 어렵고 이해하기 어렵기 때문에, 어셈블리어는 기계어에 대한 추상화된 형태의 표현으로 각 명령어들이 어떤 기능을 수행하는지 이해하기 쉽도록 만들어졌다.
어셈블리어 명령어는 기본적으로 CPU가 수행하는 명령어와 일대일로 대응된다. 이 명령어들은 각각 두 부분으로 이루어져 있다. 첫 번째 부분은 명령어 코드(opcode)로, 이 명령어가 어떤 기능을 수행하는지를 나타내는 부분이다. 두 번째 부분은 피연산자(operand)로, 이 명령어가 작업을 수행할 데이터나 메모리 주소를 나타내는 부분이다.
어셈블리 명령어의 종류에는 다음과 같은 것들이 있다.
mov : 데이터를 레지스터나 메모리에 복사한다.
add/sub : 덧셈/뺄셈을 수행한다.
imul/mul : 정수 곱셈을 수행한다. 각각 부호 있는, 부호 없는 곱셈이다.
idiv/div : 정수 나눗셈을 수행한다. 각각 부호 있는, 부호 없는 나눗셈이다.
shr/shl : 비트 단위 시프트 연산을 수행한다.
cmp : 비교를 수행한다.
jmp : 분기를 수행한다. (무조건)
je/jne/jg/jl : 조건 분기를 수행한다.
call : 서브루틴(ex.함수)을 호출한다.
ret : 서브루틴에서 복귀한다.
push/pop : 스택에 값을 넣거나 꺼낸다.
xor/and/or : 비트 단위 연산을 수행한다.
lea : 주소 계산을 수행한다.
레지스터는 컴퓨터의 중앙 처리 장치(CPU) 내부에 있는 데이터 저장 공간이다. 레지스터는 고속으로 액세스할 수 있으며, 프로그램 실행 도중에 사용되는 중요한 데이터나 명령을 저장하고 처리하는 데 사용된다.
자주 쓰이는 레지스터의 이름과 용도는 다음과 같다.
RAX : Accumulator로 사용되며, 산술 연산을 수행하는 데에 자주 사용된다.
RBX : 베이스 레지스터로 사용되며, 메모리 주소 계산에 자주 사용된다.
RCX : 카운터로 사용되며, 반복문 등에서 반복 횟수를 저장하고, 함수 인수 전달 등에도 사용된다.
RDX : 데이터 레지스터로 사용되며, 입출력 명령어에서 데이터를 전달하거나, 산술 연산을 수행할 때 사용된다.
RSI : 소스 인덱스로 사용되며, 메모리 복사 등에서 복사할 데이터의 시작 주소를 저장한다.
RDI : 대상 인덱스로 사용되며, 메모리 복사 등에서 복사한 데이터를 저장할 시작 주소를 저장한다.
RBP : 베이스 포인터로 사용되며, 함수 호출 시 스택 프레임의 시작 주소를 저장한다.
RSP : 스택 포인터로 사용되며, 현재 스택의 최상위 주소를 저장한다.
R8 ~ R15 : 함수 인수 전달 등에 사용된다.
함수의 호출과 관련해서는 다음과 같은 순서로 진행된다.
컴퓨터의 메모리 구조는 다음과 같다.
[이미지 출처 - https://velog.io/@yeahg_dev]
code, data, heap 영역은 데이터가 낮은 주소부터 쌓이지만, stack 영역은 높은 주소에서부터 거꾸로 쌓인다는 특징이 있다.