Assembly
개요
Assembly(어셈블리어, 기계어 수준 언어)는 CPU가 직접 이해할 수 있는 기계어와 일대일 대응되는 저수준 언어이다. 고급 언어(C, Rust, Wave 등)가 컴파일러를 통해 기계어로 변환되는 반면, 어셈블리어는 프로그래머가 직접 하드웨어를 제어한다.
Assembly는 CPU 명령어 집합(ISA)에 직접 대응하는 언어이며, 각 프로세서마다 문법과 명령어가 다르다 (x86, ARM, RISC-V 등). 명령어는 일반적으로 명령(Mnemonic) 과 피연산자(Operand) 로 구성된다.
예시:
mov eax, 1
add eax, 2
int 0x80
위 코드는 x86 Linux 환경에서 eax 레지스터에 1과 2를 더한 뒤
시스템 호출(interrupt)을 발생시킨다.
역사
| 연도 | 사건 |
|---|---|
| 1940년대 | 초기 기계어 사용, 어셈블리 개념 등장 |
| 1950년대 | IBM 701, UNIVAC용 어셈블러 개발 |
| 1970년대 | Intel 8080, Z80, MOS 6502 등 8비트 CPU용 어셈블리 확산 |
| 1980년대 | x86 기반 PC와 함께 MS-DOS 어셈블리 개발 표준화 |
| 1990년대 | RISC 아키텍처 등장, ARM 확장 |
| 2000년대 | JIT, LLVM IR 등 중간언어 개념 확립 |
| 2020년대 | Wave, Whale, WAIL 등 현대 IR·ASM 융합 언어 등장 |
구조
어셈블리 코드는 일반적으로 다음과 같은 세 부분으로 구성된다.
| 구분 | 설명 | 예시 |
|---|---|---|
| 데이터 섹션 | 상수, 변수, 문자열 저장 | .data, .bss
|
| 코드 섹션 | 실행 가능한 명령어 집합 | .text
|
| 엔트리 포인트 | 프로그램 시작 지점 | _start, main
|
기본 문법
어셈블리 명령어는 연산자(Mnemonic) 와 피연산자(Operand) 로 구성된다.
mov eax, 10 ; 10을 eax 레지스터에 저장
add eax, 5 ; eax = eax + 5
sub eax, 3 ; eax = eax - 3
jmp label ; label로 점프
주요 연산 범주는 다음과 같다.
| 분류 | 예시 명령어 | 설명 |
|---|---|---|
| 데이터 이동 | MOV, PUSH, POP | 메모리 ↔ 레지스터 간 데이터 이동 |
| 산술 연산 | ADD, SUB, MUL, DIV | 기본 연산 수행 |
| 논리 연산 | AND, OR, XOR, NOT | 비트 단위 논리 연산 |
| 제어 흐름 | JMP, JE, JNE, CALL, RET | 조건 분기 및 서브루틴 호출 |
| 시스템 호출 | INT, SYSCALL, SYSENTER | OS와의 인터페이스 |
어셈블리 언어별 예시
| 아키텍처 | 명령어 예시 | 설명 |
|---|---|---|
| x86 | mov eax, 1 / int 0x80 |
고전적인 인텔 구조, PC 중심 |
| x86-64 | mov rax, 60 / syscall |
64비트 Linux 커널 호출 방식 |
| ARM | MOV R0, #1 / BL printf |
임베디드 및 모바일 환경 |
| RISC-V | addi x1, x0, 5 / ecall |
오픈소스 ISA, 차세대 구조 |
| MIPS | add $t0, $t1, $t2 |
단순한 명령 구조의 교육용 ISA |
어셈블러
어셈블리 코드를 기계어로 변환하는 프로그램을 어셈블러(Assembler) 라 한다.
대표 어셈블러 목록:
| 어셈블러 | 지원 아키텍처 | 특징 |
|---|---|---|
| NASM | x86 / x86-64 | 오픈소스, Linux/Windows 지원 |
| MASM | x86 / x64 | Microsoft 공식 어셈블러 |
| FASM | x86 / x64 | 완전 독립형, 빠른 빌드 속도 |
| GAS (GNU Assembler) | 다중 ISA | GNU Toolchain 기본 구성 |
| YASM | x86 / x64 | NASM 호환, LLVM 지원 |
| LLVM Assembler | 다중 ISA | LLVM IR → 기계어 변환 |
| WAIL Assembler | Whale Toolchain | Wave 전용 IR 통합 어셈블러 |
고급 언어와의 관계
- C 언어는 어셈블리와 일대일 대응되는 구조를 가지며,
대부분의 시스템 언어(Rust, Wave)는 내부적으로 어셈블리 생성 단계를 거친다.
- 컴파일러는 AST → IR → Assembly → Machine Code 순으로 변환한다.
- Inline Assembly를 통해 C, Rust 등에서도 직접 명령어를 삽입할 수 있다.
예시 (C 코드 내 인라인 어셈블리):
int sum(int a, int b) {
int result;
__asm__ ("addl %%ebx, %%eax;"
: "=a" (result)
: "a" (a), "b" (b));
return result;
}
현대적 활용
- 부트로더 – 시스템 초기화 코드 (ex: GRUB, UEFI)
- 운영체제 커널 – CPU 제어, 인터럽트 처리
- 임베디드 시스템 – 제한된 자원 환경에서 직접 제어
- 보안 / 리버스 엔지니어링 – 바이너리 분석 및 취약점 탐지
- 컴파일러 개발 – 백엔드 코드 생성 테스트
- 에뮬레이터 – ISA 시뮬레이션
현대 트렌드
- LLVM IR – 중간 표현의 표준화로 직접 어셈블리 작성 감소
- RISC-V – 오픈 ISA로 인한 학습용 어셈블리 확산
- WAIL Assembly Integration Layer – 현대식 모듈형 어셈블리 구조
- Rust / Wave – 안전한 저수준 제어 언어 부상
- 컴파일러 자동 최적화 – 인간보다 효율적인 어셈블리 생성
관련 개념
| 개념 | 설명 |
|---|---|
| 기계어 | CPU가 실제로 실행하는 이진 명령어 |
| ISA (명령어 집합 아키텍처) | CPU 명령 체계 정의 (x86, ARM, RISC-V) |
| 레지스터 | CPU 내부의 초고속 저장소 |
| 스택 / 힙 | 메모리 구조 제어 방식 |
| 링크 스크립트 | 코드/데이터 메모리 배치 정의 |
| IR (Intermediate Representation) | 어셈블리 전 단계의 중간 표현 |
같이 보기
참고 문헌
- Randall Hyde, The Art of Assembly Language (No Starch Press, 2021)
- Paul Carter, PC Assembly Language
- Intel Developer Manual, Volume 2: Instruction Set Reference
- ARM Architecture Reference Manual v8
- RISC-V ISA Specification (v2.2)
- GNU Assembler (GAS) Documentation
- LLVM Language Reference Manual