어셈블리어

어셈블리어(Assembly language)는 중앙 처리 장치가 실행하는 기계어 명령을 사람이 읽고 작성하기 쉬운 기호와 명령어 이름으로 표현하는 저수준 프로그래밍 언어의 총칭이다. 숫자로 된 연산 코드와 메모리 주소를 MOV, ADD, JMP와 같은 명령어 니모닉, 레지스터 이름, 레...

영문명Assembly language
분류저수준 프로그래밍 언어
실행 방식어셈블러를 통한 기계어 변환
추상화 대상명령어 집합 아키텍처
주요 구성 요소명령어 니모닉, 피연산자, 레지스터, 레이블, 지시어
주요 계열x86, x86-64, Arm, AArch64, RISC-V, MIPS, Power ISA, IBM Z
주요 구현체GNU Assembler, NASM, MASM, FASM, LLVM Integrated Assembler
파일 확장자.asm, .s, .S

어셈블리어(Assembly language)는 중앙 처리 장치가 실행하는 기계어 명령을 사람이 읽고 작성하기 쉬운 기호와 명령어 이름으로 표현하는 저수준 프로그래밍 언어의 총칭이다. 숫자로 된 연산 코드와 메모리 주소를 MOV, ADD, JMP와 같은 명령어 니모닉, 레지스터 이름, 레이블과 기호로 나타내며, 작성된 소스 코드는 어셈블러에 의해 기계어 또는 오브젝트 파일로 변환된다.[1]

어셈블리어는 하나의 공통된 언어가 아니다. 각 어셈블리어는 특정 명령어 집합 아키텍처와 밀접하게 연결되어 있으며, x86-64용 코드와 AArch64용 코드는 사용할 수 있는 명령어, 레지스터, 주소 지정 방식과 호출 규약이 서로 다르다. 같은 아키텍처에서도 GNU Assembler의 AT&T 문법과 Intel 문법처럼 어셈블러와 개발 도구에 따라 표기 방식이 달라질 수 있다. Intel의 아키텍처 설명서도 프로세서의 프로그래밍 환경과 명령어 집합을 별도의 참조 체계로 정의한다.[2]

일반적인 어셈블리 명령은 기계 명령 하나와 가까운 관계를 가지지만, 모든 문장이 반드시 하나의 기계 명령으로 직접 대응하는 것은 아니다. 어셈블러 지시어는 실행 명령을 만들지 않고 데이터 배치, 섹션 구성과 심벌 정의를 제어할 수 있으며, 의사 명령어는 어셈블러에 의해 하나 이상의 실제 명령으로 변환될 수 있다. 매크로와 조건부 어셈블리 기능을 제공하는 구현체도 있으므로 어셈블리 소스는 단순한 기계어의 문자 치환보다 넓은 표현 능력을 가진다. GNU Assembler 역시 여러 프로세서용 문법과 기계 의존 기능, 지시어와 매크로 기능을 제공한다.[3]

초기 컴퓨터에서는 프로그램을 수치 형태의 기계어로 직접 작성해야 했으나, 어셈블리어와 어셈블러가 도입되면서 연산 코드와 기억 장소를 숫자 대신 이름으로 나타낼 수 있게 되었다. 다만 초기 어셈블리어도 일반적으로 프로세서 명령 하나마다 소스 코드 한 줄을 작성해야 했으며, 이러한 하드웨어 의존성과 낮은 추상화 수준은 이후 FORTRAN, COBOL, Lisp과 같은 고급 프로그래밍 언어가 발전하는 배경 가운데 하나가 되었다.[4]

현대 소프트웨어의 대부분은 C (프로그래밍 언어), C++, Rust와 같은 고급 언어로 작성되지만, 어셈블리어는 부팅 코드, 운영체제의 아키텍처 의존 부분, 인터럽트와 문맥 교환, 임베디드 시스템, 장치 제어, 암호화 루틴, 벡터 명령 최적화와 역공학 등에서 계속 사용된다. 또한 컴파일러가 생성한 명령을 분석하거나 프로세서의 레지스터, 메모리 모델, 호출 규약과 실행 과정을 이해하기 위한 수단으로 활용된다.

역사

기계어 프로그래밍

기호식 명령 표현의 등장

초기 어셈블러

고급 프로그래밍 언어의 등장

마이크로프로세서와 개인용 컴퓨터

현대의 어셈블리어

기본 개념

명령어 집합 아키텍처

기계어와 어셈블리어

명령어 니모닉

피연산자

레지스터

메모리와 주소

레이블과 심벌

어셈블러 지시어

의사 명령어와 매크로

명령어와 데이터 표현

명령어 형식

데이터 이동

산술과 논리 연산

비교와 조건 분기

반복과 제어 흐름

스택 연산

함수 호출과 반환

데이터 정의와 정렬

문자열과 상수

레지스터와 메모리

범용 레지스터

특수 목적 레지스터

상태 레지스터와 플래그

주소 지정 방식

바이트 순서

메모리 정렬

스택과 힙

가상 메모리와 주소 공간

어셈블 과정과 도구 체인

어셈블러

전처리와 매크로 확장

섹션과 심벌 테이블

오브젝트 파일

링커

로더

정적 링크와 동적 링크

실행 파일 형식

디버거와 디스어셈블러

문법과 방언

명령어 표기 방식

Intel 문법

AT&T 문법

어셈블러별 확장

대소문자와 식별자

주석과 소스 구성

이식성과 호환성

주요 명령어 집합 계열

x86과 x86-64

Arm과 AArch64

RISC-V

MIPS

Power ISA

IBM Z

SPARC

6502

Z80

기타 명령어 집합

프로그래밍 모델

절차와 함수

호출 규약

매개변수와 반환값

레지스터 보존 규칙

스택 프레임

시스템 호출

인터럽트와 예외

동시성과 원자적 연산

고급 언어와의 관계

컴파일러가 생성하는 어셈블리 코드

인라인 어셈블리

외부 어셈블리 모듈

외부 함수 인터페이스

런타임과 표준 라이브러리

최적화와 자동 벡터화

개발 도구

GNU Assembler

NASM

MASM

FASM

LLVM Integrated Assembler

디버거

디스어셈블러

프로파일러와 성능 분석기

활용 분야

운영체제와 커널

부트로더와 펌웨어

임베디드 시스템

장치 드라이버

실시간 시스템

암호학과 SIMD 최적화

게임과 그래픽스

컴파일러 개발

역공학과 보안 분석

교육과 컴퓨터 구조 학습

최적화

명령어 선택

명령어 수준 병렬성

파이프라인과 지연 시간

캐시와 메모리 접근

분기 예측

SIMD와 벡터 명령

코드 크기와 실행 속도

마이크로아키텍처 의존성

장점과 한계

영향

관련 문서

  1. IBM: The Assembler language on z/OS
  2. Intel: Intel 64 and IA-32 Architectures Software Developer’s Manuals
  3. GNU Binutils: Using as
  4. Computer History Museum: Higher Level Languages