8086 어셈블리 언어

2025. 4. 4. 00:34어셈블리 프로그래밍

어셈블리언어 문법

  • 대소문자를 구분하지 않음! 
MOW와 mow는 동일!
  • 어셈블리언어의 문장은 4개의 필드로 구성됨
이름(name) 연산자(operator) 오퍼랜드(operands) 설명(comment)
  • 다음은 어셈블리언어의 문장을 작성할 수 있음
이름  연산자  오퍼랜드  설명
TOP:  MOV     AX,10     ;AX 레지스터에 10을 저장함!

 

  • 이름 필드
-명령어의 레이블, 프로시져 이름, 변수 이름 등을 나타냄
-최대 31자
-문자, 숫자, 특수문자(?, ., @, _, $, %) 사용가능 (마침표는 맨 앞에만 사용가능함)
-빈칸은 허용 안됨
-숫자로 시작하면 안됨

cf) 불가능한 이름
TOP LOOP ;띄어 쓰기 불가능
3SSJJSS ;숫자를 맨앞에 사용하는 것은 불가능
ABC11.1 ;마침표는 첫번째에만 사용 가능
ASSEM*AS ;사용가능한 특수문자 이외는 사용불가​
  • 연산자 필드: 프로세서에서 수행하는 기호화된 명령어 혹은 어셈블리 지시자 등의 의사 명령어
  • 오퍼랜드 필드: 연산자에 의해서 데이터를 지정하는 필드
DEC AX ;AX 레지스터의 내용을 1 감소
ADD AX,10 ;AX 레지스터의 내용을 10 더하기
  • 설명 필드: 세미콜론을 활용하여서 코멘트를 덧붙임.

데이터와 변수 정의

  • 10진수: 숫자+D/d(D/d는 생략 가능)
  • 2진수: 숫자+B/b
  • 16진수: 숫자+H/h (16진수인 경우 문자가 알파벳으로 시작하면 맨 앞에 0을 추가해줘야 함)
ex)
10110 ;십진수를 의미
1011001B ;2진수를 의미
0FFFFH /;16진수를 의미

3,567 ;숫자표현에서 콤마 사용 불가 => 3567로 변경
4FFF ;16진수를 표현할 때는 뒤에 H/h를 추가해야 함 => 4FFFH로 변경
FFFH ;16진수가 알파벳으로 시작하면 0을 맨 앞에 추가해야 함 => 0FFFH

 

  • 문자와 문자열의 경우 홑따옴표나 큰따옴표로 표현함. (여기서는 대소문자를 구분함!)
  • 대문자 'A'의 아스키코드는 41H 이기 때문에 다음과 같이 표기할 수 있음.
MOV DL,'A' ;A를 DL레지스터에 저장
MOV DL,41H ;41H, 즉 A를 DL레지스터에 저장

변수의 정의

  • 변수는 데이터형을 가짐.
  • 메모리의 주소를 위해 데이터 세그먼트의 옵셋 주소가 할당됨.
  • 데이터형은 다음과 같은 것이 존재.
데이터형 크기
DB 1바이트
DW 2바이트
DD 4바이트
DQ 8바이트
DT 10바이트
  • 변수를 초기화할 때 DB를 활용하면 2바이트로 크기를 할당하고 초기값을 설정해 줌.
  • 이때 초기값이 필요 없을 때는 ?로 나타냄.
AB DB 10 ;초기값이 10인 바이트 변수
AC DB ? ;초기값을 설정하지 않은 바이트 변수
  • DW는 2바이트, 즉 16비트로 변수의 크기를 지정함.
  • 8086이 16비트 프로세서의 가장 기본이 되기 때문에 주로 DW를 사용함.
AB DW 16 ;초기값이 16인 2바이트 변수
AC DW ? ;초기값을 설정하지 않은 2바이트 변수
  • 배열과 같은 경우 동일한 크기의 연속적인 메모리 변수를 나타냄.
  • 배열과 같은 경우에는 다음과 같이 정의함.
AB DB 10H,20H,30H,80H ;바이트 배열로 4개의 변수로 초기화해줌
AC DW 2800, 2900,3000, 8086 ;워드(2바이트) 배열로 4개의 변수로 초기화해줌
  • 문자열은 문자나 아스키코드를 활용하여 정의 가능하고, 문자열이 끝났다는 것을 프로세서가 확인하기 위해서 $(24H)로 끝내야 한다.
MSG DW 'hello',0DH, 0AH,'$' ;hello+줄바꿈(0DH:케리지 리턴, 0AH:라인 피드)+'$' => hello를 출력하고 줄바꿈
  • 상수는 EQU를 활용하여서 정의할 수 있다.
CR EQU 0DH ;CR에 케리지 리턴을 의미하는 아스키코드 0DH를 상수로 지정
MOW DL, CR ;DL 레지스터에 CR을 저장해줌

8086 명령어

  • 데이터 전송 명령어: 레지스터나 메모리 변수 사이의 데이터 전송을 위한 명령어
  • 산술 연산 명령어: 덧셈, 뼬셈, 곱셈, 나눗셈 등의 명령어
  • 논리 연산 명령어: AND, NOT, OR, XOR 등의 명령어
  • 흐름 제어 명령어: 조건문, 반복문, 프로시져 호출 및 복귀 등의 프로그램 제어 명령어

MOV 명령어

  • 레지스터 사이와 레지스터와 메모리 변수 사이의 데이터를 전송하는 명령어.
  • 레지스터나 메모리 변수에 상수 값을 저장하는 것도 가능함.
MOV AX,DX ;DX레지스터의 내용을 AX에 저장
MOV BX,SSJ ;변수 SSJ의 내용을 BX에 저장
MOV CX,2500 ;2500을 CX레지스터 저장
  • MOV를 해도 근원지 오퍼랜드의 내용은 사라지지 않는다!
  • 다음은 근원지 오퍼랜드와 목적지 오퍼랜드사이에서 전송 가능한지 불가능한지에 대한 표이다.
근원지 오퍼랜드 목적지 오퍼랜드
일반 레지스터 세그먼트 레지스터 메모리 변수 상수
일반 레지스터 가능 가능 가능 불가능
세그먼트 레지스터 불가능 가능
메모리 변수 가능 불가능
상수 불가능 가능

XCHG 명령어

  • 두 레지스터와 레지스터와 메모리 변수의 내용을 변경하는 명령어.
  • 메모리 변수끼리 변경하는 것은 불가능하다!
XCHG DL, AL ;AL, DL의 내용을 서로 변경

ADD와 SUB 명령어

  • ADD 명령어는 두 내용을 더하거나 레지스터와 메모리 변수의 내용을 더하는 데 사용하는 명령어.
  • 보통은 오퍼랜드가 두 개여서 근원지 오퍼랜드와 목적지 오퍼랜드로 구분.
  • ADD 명령어는 메모리 변수와 메모리 변수끼리는 연산 불가능하다!
ADD AX, BX ;AX와 BX를 더하고 AX에 저장
ADD CL,10 ;CL의 내용에 10을 더한 뒤 CL에 저장
  • SUB 명령어는 두 내용을 더하거나 레지스터와 메모리 변수의 내용을 빼는 데 사용하는 명령어.
  • 보통은 오퍼랜드가 두 개여서 근원지 오퍼랜드와 목적지 오퍼랜드로 구분.
  • ADD명령어와 동일하게 메모리 변수와 메모리 변수끼리는 연산 불가능하다!
SUB BX,DX ;BX의 내용에 DX의 내용을 빼고 나서 BX에 저장
SUB AX, 16 ;AX의 내용에 16을 빼고 나서 AX에 저장
근원지 오퍼랜드 (ADD, SUB) 목적지 오퍼랜드
일반 레지스터 메모리 변수
일반 레지스터 가능 가능
메모리 변수 가능 불가능
상수 가능 가능

INC와 DEC 명령어

  • INC와 DEC는 각각 1을 더하거나 빼는 명령어.
  • 하나의 오패랜드만 사용한다.
INC CL ;CL의 내용을 1증가 시킴
INC SSJ ;SSJ의 내용을 1증가 시킴

DEC CL ;CL의 내용을 1감소 시킴
DEC SSJ ;SSJ의 내용을 1감소 시킴

NEG와 NOT 명령어

  • NEG명령어는 레지스터나 메모리 변수의 데이터의 부호를 반대로 변경 명령어.
  • 프로세서는 2의 보수를 실행하여 양수는 음수로 음수는 양수로 변환함.
NEG WRD ;WRD의 부호를 변경
NEG AX ;AX의 부호를 변경
  • NOT명령어는 레지스터나 메모리 변수에 저장된 데이터의 각 비트를 반대로 변환하는 명령어
  • 1의 보수를 구하는 데 활용.
NOT CX ;CX의 1의 보수를 CX에 저장

주의사항

  • 모든 명령어는 메모리 변수를 근원지와 목적지 변수로 동시에 사용할 수 없다! (메모리 변수 내용을 레지스터에 저장시킨 후 연산을 적용해야 함)
  • 두 개의 오퍼랜드를 사용하는 명령어에서 목적지 오퍼랜드와 근원지 오퍼랜드의 데이터형은 일치해야 한다.
.DATA
BYT DB 10
...
MOV AL,BX ;BX는 16비트, AL은 8비트 이므로 불가능
MOV CX, BYT ;CX는 16비트, BYT는 8비트 이므로 불가능

고급언어를 프로그래밍 언어로 변환

  • B = A - 2 * C
MOV AX, A ;AX레지스터에 A저장
SUB AX, C ;AX에 C를 뺴고 난 후 저장
SUB AX, C ;AX에 C를 뺴고 난 후 저장
MOV B, AX ;AX레지스터의 내용을 B에 저장
  • C = A * 4 - B * 2 - 10
MOV AX,A
ADD AX,AX ;A+A
ADD AX,AX ;AX가 2*A 이므로 AX+AX=4*A
SUB AX,B ;AX-B=4*A-B
SUB AX,B ;AX-B=4*A-2*B
SUB AX,10 ;AX-10=4*A-2*B-10
MOV C,AX ;AX의 내용을 C에 저장

어셈블리 프로그램 구조

  • 메모리 모델 정의, 스택 크기 지정, 데이터 세그먼트 구성, 코드 세그먼트로 구성됨

메모리 모델

  • 프로그램의 코드와 데이터의 크기를 나타냄.
  • 메모리 모델은 프로그램 코드와 데이터가 1개의 세그먼트(64KB)에 저장될 수 있는지에 따라 5개의 모델로 나누어진다.
메모리 모델 설명
SMALL 한 세그먼트에 저장할 수 있는 코드
한 세그먼트에 저장할 수 있는 데이터
MEDIUM 한 세그먼트 이상에 저장할 수 있는 코드
한 세그먼트에 저장할 수 있는 코드
COMPACT 한 세그먼트에 저장할 수 있는 코드
한 세그먼트 이상헤 저장할 수 있는 데이터
LARGE 한 세그먼트 이상에 저장할 수 있는 코드
64KB 이상이 되지 않는 배열
HUGE 한 세그먼트 이상에 저장할 수 있는 코드와 데이터
64KB 이상이 되는 배열
.MODEL 메모리 모델(memory model)
  • 보통 한 세그먼트에는 약 2만 개 이상의 어셈블리 언어 문장이 저장될 수 있기 때문에 대부분의 프로그램은 SMALL을 사용한다.

데이터 세그먼트

  • 프로그램에서 사용하는 바이트, 워드 변수와 배열, 문자열 등의 메모리 변수를 선언.
  • 프로그램에서 활용되는 모든 메모리 변수가 저장됨.
.DATA ;데이터 세그먼트
SSJ DB 10 ;메모리 변수들을 선언!
WRD DW ?

스택 세그먼트

  • 어셈블리 프로그램은 여러 가지 프로시져를 사용하여 작성되기에 프로시져 호출 전후의 데이터를 유지해야 하는 레지스터나 메모리 변수의 내용은 호출된 프로시져의 코드를 실행하기 전에 스택에 저장되어야 함.
  • 스택에 데이터를 저장하고 복원하는 것은 프로그램을 실행하는 중간에 발생하기 때문에 스택 영역은 데이터 세그먼트와 별도의 메모리 세그먼트에 설정되어야 함.
  • 프로그램이 복잡해지면 데이터 수가 복잡해지기 때문에 스택 공간을 얼마나 사용하는지 알려 주어야 한다.
.STACK 100H ;스택 영역으로 100H, 즉 256바이트를 지정

코드 세그먼트

  • 코드 세그먼트는 8086 명령어들을 사용하여 작성된 어셈블리언어의 문장들을 포함.
  • 어셈블리 언어는 프로시져 단위로 구성되며, 최소 1개 이상이 존재해야 하고, 그중에 MAIN프로시져를 포함하여야 함.
.CODE 이름(name)

어셈블리 프로그램의 구조

  1. 메모리 모델 정의
  2. 스택 영역의 크기를 지정
  3. 메모리 변수를 사용하는 경우 데이터 세그먼트를 정의
  4. 코드 세그먼트에 알고리즘에 따라 코드 작성

'어셈블리 프로그래밍' 카테고리의 다른 글

조건문 구조(2)  (0) 2025.05.22
조건문 구조  (0) 2025.05.22
플래그 래지스터&디버거  (0) 2025.04.27
문자 입출력  (0) 2025.04.13
8086 프로세서  (0) 2025.03.25