이 문서는 어셈블리어 기초 개념을 설명하며, 소스 코드 작성부터 실행 가능한 프로그램으로 변환되는 과정을 다룹니다.
소스에서 실행 파일까지의 과정
어셈블리 프로그램 개발 과정은 다음 단계로 구성됩니다:
- 어셈블리 소스 코드 작성
- 컴파일러를 사용한 컴파일 및 링크
- 생성된 실행 파일 실행
실행 파일은 프로그램 코드와 데이터, 그리고 관련 설명 정보(프로그램 크기, 메모리 요구량 등)를 포함합니다.
기본 소스 프로그램 구조
기본적인 소스 프로그램 예시:
assume cs:program_segment
program_segment segment
mov cx, 0abcdH
mov dx, 01234H
add cx, dx
add cx, cx
mov ax, 4c00H
int 21H
program_segment ends
end
가상 지시어
어셈블리어에는 두 가지 지시어가 있습니다:
- 실제 기계어로 변환되는 어셈블리 지시어
- 컴파일러가 처리하는 가상 지시어(의사 지시어)
주요 가상 지시어:
segment와ends: 세그먼트 정의end: 프로그램 종료 표시assume: 세그먼트 레지스터 연결
컴파일 및 링킹
컴파일은 다음 명령으로 수행:
masm 파일명;
링킹은 다음 명령으로 수행:
link 파일명;
링커의 역할:
- 여러 오브젝트 파일 결합
- 라이브러리 함수 연결
- 실행 가능한 정보 생성
프로그램 실행 및 디버깅
프로그램 실행은 파일명 직접 입력으로 가능합니다. 디버깅은 debug.exe를 사용하여 단계별 실행 추적이 가능합니다.
[BX]와 loop 명령어
메모리 접근 방법:
mov si, [di] ; DI가 가리키는 메모리 내용을 SI에 저장
mov bl, [si+5] ; SI+5 위치의 바이트를 BL에 저장
loop 명령어 형식:
loop 레이블
loop 명령어는 CX 레지스터 값을 1 감소시키고, CX가 0이 아닌 경우 지정된 레이블로 점프합니다.
loop 사용 예시
assume cs:calc
calc segment
mov ax, 3
mov cx, 10
repeat:
add ax, ax
loop repeat
mov ax, 4c00H
int 21H
calc ends
end
메모리 주소 지정 방법
어셈블리에서는 다양한 메모리 주소 지정 방식을 제공합니다:
- 직접 주소 지정:
[상수] - 레지스터 간접 주소 지정:
[레지스터] - 상대 주소 지정:
[레지스터+상수] - 기반 인덱스 주소 지정:
[bx+si] - 상대 기반 인덱스 주소 지정:
[bx+si+상수]
세그먼트 접두사
메모리 접근 시 명시적으로 세그먼트를 지정할 수 있습니다:
mov ax, ds:[bx] ; DS 세그먼트 사용
mov ax, es:[di] ; ES 세그먼트 사용
여러 세그먼트 사용
프로그램을 구조화하기 위해 코드, 데이터, 스택을 별도 세그먼트로 분리할 수 있습니다:
assume cs:code, ds:data, ss:stack
data segment
dw 1234H, 5678H, 9abcH, 0defH
data ends
stack segment
dw 0, 0, 0, 0, 0, 0, 0, 0
stack ends
code segment
start:
mov ax, data
mov ds, ax
mov ax, stack
mov ss, ax
mov sp, 10H
mov bx, 0
mov cx, 4
s: push [bx]
add bx, 2
loop s
mov bx, 0
mov cx, 4
s2: pop [bx]
add bx, 2
loop s2
mov ax, 4c00H
int 21H
code ends
end start
비트 연산과 문자 처리
and와 or 명령어를 사용한 비트 조작:
mov al, 01010101B
and al, 11110000B ; 상위 4비트만 유지
mov al, 01010101B
or al, 00001111B ; 하위 4비트를 1로 설정
문자 데이터는 작은따옴표로 표현할 수 있습니다:
mov al, 'A' ; mov al, 41H와 동일
SI와 DI 레지스터 활용
SI(소스 인덱스)와 DI(목적지 인덱스)는 메모리 주소 지정에 사용됩니다:
mov si, 0
mov di, 16
mov cx, 8
copy_loop:
mov ax, [si]
mov [di], ax
add si, 2
add di, 2
loop copy_loop
고급 주소 지정 방식
여러 레지스터를 조합한 주소 지정:
mov ax, [bx+si] ; BX와 SI 값의 합으로 주소 지정
mov ax, [bx+di+5] ; BX, DI, 상수 5의 합으로 주소 지정
mov ax, 10[bx][si] ; 위와 동일한 다른 표기법
실용적인 예제
문자열 대소문자 변환:
data segment
db 'Programming'
db 'Language'
data ends
code segment
start:
mov ax, data
mov ds, ax
mov bx, 0
mov cx, 11
to_upper:
mov al, [bx]
and al, 11011111B
mov [bx], al
inc bx
loop to_upper
mov bx, 11
mov cx, 8
to_lower:
mov al, [bx]
or al, 00100000B
mov [bx], al
inc bx
loop to_lower
mov ax, 4c00H
int 21H
code ends
end start
배열 데이터 처리:
assume cs:main_prog, ds:array_data
array_data segment
dw 100, 200, 300, 400, 500
array_data ends
main_prog segment
start:
mov ax, array_data
mov ds, ax
mov bx, 0
mov si, 0
mov cx, 5
sum_array:
mov ax, [bx+si]
add [sum], ax
add si, 2
loop sum_array
mov ax, 4c00H
int 21H
main_prog segment
end start