크리에이티브 커먼즈 라이센스

홈페이지HOME

PHP

JavaScript

HTML

CSS

드롭다운메뉴

제로보드4

도   움   말

백지 건강강좌/자가임상체험

물박사(자가면역질환...)^미러

전동명(천연물질사전)^미러

竹田 장승옥(블로그)^글목록

계산환산(계산기)^ 단위변환

관주성경 TTS 일반파일 TTS

바이블로 Bible_ro 다운로드

다운로드>폰에 복사
>파일선택...설치됩니다.

[도움말 보기] 바로가기

개선 요구, 충고는
아래 관리자 연락
전화/메일 부탁 드립니다.
최대한 빨리 처리하고
업데이트 올리겠습니다.


asm_71.

제 2 절  MOV 명령과 문자 출력

앞 장에서 간단하게 만들어 실행해 본 문자 출력 프로그램의 내용을 깊이 분석하면서

문자 출력을 위한 mov 명령에 대하여 정리해 보자.


     ## 필자통신

    이 파일은 이형문님의 다음 원고를 재편집 보충한 것이다.

    10 이형문 buju8t 12/16 1908 14 MOV 명령을 알아

    봅시다.



1. 전송 명령의 3가지 형

앞 장의 프로그램에서 우리는 출력할 문자에 대응하는 아스키 코드값 증 수치를

레지스터에 전송하기 위해 mov 명령을 사용하였다.

그 프로그램에서 우리는 수치를 레지스터로 직접 전송하기도 했고, 다른 레지스터에

있는 수치를 목적 레지스터로 전송도 해 보았다.

수치 등의 데이터를 전송하는 방법에는 다음과 같은 3가지가 있다.


    1.테지스터에 수치를 대입한다.

    2.레지스터와 레지스터 사이에서 데이터를 전송한다.

    3.레지스터와 메모리 사이에서 데이터를 전송한다.


우리가 만들어 본 프로그램에서 우리는 처음에는 직접 레지스터로 수치를 전송하였고,

한 번은 다른 레지스터에 전송되어 있던 수치를 목적하는 레지스터로 자시 전송하는

방법을 사용하였다.






그 프로그램은 화면에 AB를 표시하는 프로그램이었다.

프로그램 소스 파일을 다시 옮겨 두고 내용을 분석하기로 한다.


    1:

    2: MAIN  SEGMENT

    3:  ASSUME  CS:MAIN

    4:  ;

    5: MOV DL,41H

    6: MOV AH,2

    7: INT 21H

    8: MOV DL,'B'

    9: MOV BL,2

    10:  MOV AH,BL

    11:  INT 21H

    12: ;

    13:  MOV AH,4CH

    14:  INT 21H

    15: ;

    16:  MAIN  ENDS

    17:  END

    18:







2. 소스 리스트의 형식

소스 파일에서 소스 리스트(SOURCE LIST)의 형식(FORMAT)을 차례로 살펴 보자.


1) MAIN SEGMENT, MAIN ENDS

둘째 줄에 보이는 MAIN SEGMENT는 의사명령의 일종으로, <이것은 "MAIN"이라는

이름의 세그먼트가 할당되는 프로그램의 시작이다>라는 뜻의 선언문이다.

이 의사명령은 16번째 줄의 MAIN ENDS와 짝이 되고 있어서 이 두 문장 안에 들어간

부분이 "MAIN"이라는 세그먼트 속에 들어가는 프로그램이다.

이 소스 파일에서는 세그먼트의 이름을 MAIN 이라고 했지만, 세그먼트의 이름은

어떻게 짓든지 작성자 임의로 지으면 그만이지만, "MOV"나 "INT"

등 어셈블리 명령과 같은 이름은 사용할 수 없다.

또한 명령의 길이도 자유이지만 31문자를 넘는 부분은 구별하지 않는다.


2) ASSUME  CS:MAIN

3번째 줄의 의사명령 ASSUME CS:MAIN은 어셈블러가 어셈블을 할 때 <코드 세그먼트(CS:)를

참조하는 명령이 있다면, MAIN 이라는 이름의 세그먼트를 참조하라>는 뜻의 선언을

하는 문장이다.

ASSUME 문장은 4개 세그먼트(CS,DS,SS,ES)와 세그먼트 이름을 대응시키는 선언문이다.

코드 세그먼트를 참조하는 명령은 CS를 선언한다. 데이터 세그먼트를 참조하는 명령은

DS를 선언한다.

assume 문장이 필요한 이유는 무엇일까? 매크로 어셈블러에서는 소스 파일을 여러

개의 세그먼트로 분할하여 작성하고 나중에 그것들을 결합시켜 하나의 프로그램으로

만드는 방법을 선택하고 있기 때문에, 선언한 4개의 세그먼트가 어느 이름의 세그먼트와

대응하고 있는가를 표시해야 할 필요가 있기 때문이다.


3) END

17번째 줄의 의사명령 END는 어셈블러 소스 리스트의 끝을 나타내며 프로그램의

끝에는 반드시 END 문장을 입력해 주어야 된다.

어셈블에서 END 문 이후에 쓰여진 문장은 모두 무시된다.






3. 어셈블러 프로그램의 기본형

지금 우리는 간단한 어셈블러 프로그램을 보고 있다.

이 프로그램에서 어셈블러 프로그램의 기본형을 간추려 보자.


     +----------------------------------+

     [MAIN] SEGMENT  

    ASSUME

     CS:[MAIN]  

     

    본문


     

     [MAIN] ENDS

    END

     

     +----------------------------------+


앞 장에서 이미 설명했지만, 가운데 본문에 해당되는 부분을 16진수 뒤에 붙이는

h 표시만 제거하고 그대로 또는 일부 표현이 허용되지 않는 부분만을 수정하여 디버그로써도

간단한 프로그램을 얼마든지 만들 수 있다.


4. 설명문(COMMENT)을 쓰는 법

4, 12, 15번째 줄의 ;는 설명문의 시작을 표시한다.

세미콜론(;) 다음에 쓰여진 문자는 설명문으로 간주되어 어셈블되지 않는다.

설명문은 줄 처음부터 또는 줄의 중간 이후부터 쓸 수 있다.

다음과 같은 줄에서 세미콜론 이전은 어셈블되며, 그 이후는 되지 않는다.


    MOV  DL,41H  ;41H="A"







5. 8086 레지스터의 구성

AX,BX,CX,DX의 4가지 범용 레지스터는 주로 연산에 사용되며 사용 빈도가 높은

레지스터들이다. 이 레지스터들은 16비트의 크기를 가지고 있지만 상위 8비트와 하위

8비트로 나누어 각각 별도의 레지스터처럼 사용할 수 있다.

그와 달리, 범용 레지스터 SI,DI,BP,SP는 16비트로만 사용이 가능다.

다음의 그림은 범용 레지스터 중에 상위/하위 각 8비트로 나누어 쓸 수도 있는

4개의 레지스터와 16비트로만 사용되는 4개의 레지스터, 익스트럭션 포인트 및 플래그

레지스터, 4개의 세그먼트 레지스터 등을 차례로 보여 준다.


    <------16 비트--------->

    <--8비트-->  <--8비트-->

    +-----------+----------+

    AX: AH  AL

     어큐뮬레이터 레지스터

    +-----------+----------+

    BX:  BH  BL

    베이스 레지스터

    +-----------+----------+

    CX:  CH  CL

    카운터 레지스터

    +-----------+----------+

    DX:  DH  DL

    데이터 레지스터

    +-----------+----------+

    ##

    이상은 상/하위 구분 사용이 가능한 범용 레지스터 ##

    +----------------------+

    SP

     스택 포인터

    +----------------------+

    BP

     베이스

    포인터

    +----------------------+

    SI

     소스 인덱스

    +----------------------+

    DI

     데스티

    네이션 인덱스

    +----------------------+

    ##

    이상은 16비트 전체로만 사용되는 범용 레지스터 ##

    +----------------------+

    IP

     익스트럭션

    포인터

    +----------------------+

    FL

     플래그

    레지스터

    +----------------------+

    ##

    이상은 특수한 용도의 레지스터 ##


    +----------------------+

    CS

     코드 세그먼트

    레지스터

    +----------------------+

    DS

     데이터

    세그먼트 레지스터

    +----------------------+

    SS

     스택 세그먼트

    레지스터

    +----------------------+

    ES

     익스트라

    세그먼트 레지스터

    +----------------------+

    ##

    이상은 세그먼트 레지스터 ##


결국 14개의 8086 레지스터 중에서 상/하 각 바이트(8비트)를 별도의 레지스터처럼

사용할 수 있는 것은 범용 레지스터 AX, BX, CX, DX 등 4개 뿐이며 그 나머지 레지스터는

모두 워드(16비트) 전체로만 사용됨을 알 수 있을 것이다.






6. MOV 명령의 사용법

MOV는 MOVE의 약자로  레지스터로, 레지스터 사이에서, 또는 레지스터와

메모리 사이에서 수치 등의 데이터를 전송하는 데 쓰이는 명령이었다.

따라서 MOV DL,41H 명령은 DL 레지스터에 16진수 41H를 대입하라는 명령이다.


     ## 주의

    어셈블러는 사용자가 특별히 수치 뒤에 H를 붙여 그 수치가 16진수임을 표시하지

    않는 한 모든  수치는 10진수로 취급하기 때문에 16진 코드값을 입력하기

    위해서는  반드시 수치 뒤에 H를  붙여 주어야 된다. 또한 수치가

    알파벳으로 시작되는  경우에는 그것이 문자가 아니고 수치임을 알리기

    위해 수치 앞에 "0"을 붙이도록 약속하고 있다.

    16진수 4A --> 4AH 16진수

    C7 -->  0C7H



7. 시스템 호출과 입출력

우리는 프로그램에서 INT 명령을 매우 자주 사용하였다.


    INT 21H


INT는 인터럽트(interrupt)라는 명령어인데, interrupt는 영어로 가로막다 중단시키다

등의 뜻을 가지고 있다.  즉 인터럽트 명령은 CPU가 하던 일을 같제적으로 중지시키고

끼어들기(인터럽트)를 발생시키는 명령이다. 인터럽트 명령은 시스템에 내장되어

있는 어떤 기능의 루틴을 호출할 목적으로 사용되고 있다.

시스템 호출이란 운영체계(OS) 내에 미리 만들어 준비해 둔 입출력 등의 기능을

위한 서브루틴을 호출하는 일을 가리킨다.






다양한 기능의 시스템 호출을 구분하기 위해 16진수로 10H, 20H, 21H 등의 번호를

붙여 각 인터럽트를 표시한다.

한편 아무리 그렇게  번호를 붙여도 인터럽트 명령의  갯수를 무한정

만들 수는 없는 반면에 사용할 시스템 기능은 많기 때문에 세부적으로 모든 종류의

구체적인 기능에 하나 하나 일일이 입출력 인터럽트 번호를 할당할 수는 없다.

그래서 MS-DOS에서는 INT 21H 를 주로 입출력 인터럽트로 사용하면서, 입출력의

구체적인 내용을 지정하는  보조 명령(SUB-COMMAND)을 역시 번호로 구분하여

해당되는 수치를 AH 레지스터에 넣어 시스템을 호출하는 방법을 쓰고 있다.

즉 INT 21H 명령은 입출력이라는 큰 기능을 수행하되, 구체적으로 입력을 할 것인지

출력을 할 것인지 등은 AH 레지스터의 값을 참고하는 것이다.

다음의 2가지 예를 보면 훨씬 이해가 쉬울 것이다.


    MOV  AH,1

    INT  21H  -

    키보드로 부터 한문자를 입력하라는 명령은

    MOV  AH,2

    INT  21H  -

    디스플레이에 1문자를 표시하라는 명령은


즉 꼭 같은 INT 21H 명령이지만 AH 레지스터에 저장된 값이 1일 때는 한 문자의

입력을 받아 들이고, AH 값이 2일 때는 한 문자를 화면(모니터)에 출력한다.


     ## 주의

    당연한 말이지만, 일단 INT 21H 명령을 만나면 즉시 입출력이 실행되기 때문에

    구체적인 시스템 호출을  지정하는 AH 레지스터의 값은 INT 21H 명령 이전에

    입력해 두어야 된다.







이 프로그램의 경우 1문자 표시 루틴을 호출한 것인데 표시해야 할 데이터는 미리

DL 레지스터에  넣어 두어야 된다. 이  프로그램의에서 처음 나오는 INT

21H 명령이 실행될 때는 DL 레지스터에  41H 가 대입되어 있었으므로 1문자

표시 루틴에서는 아스키 코드 41H에 대응하는 문자 "A"가 화면에 표시된다.

그 다음에는 DL 레지스터에 전송할 수치 대신 해당 문자를 직접 입력하였다.


    MOV DL,  'B'


다만 따옴표 안에 문자를  싸서 입력했음에 유의해야 된다. 만약 따옴표를

빠뜨리고 입력했다면 에러가  발생할 것이다. 어셈블리에서 문자를 따옴표로

에워싼 것은 그 믄자에 상응하는 아스키 코드가 쓰여진 것으로 간주된다.

다음의 경우를 생각해 보자.


    MOV DL, '1'


여기에서 1은 아스키 코드값이  아니라 아스키 문자이다. 즉 16진수 1에

해당하는 문자를 출력하라는 뜻이 아니라 1이라는 문자를 출력하라는 주문이 된다.

DL 레지스터에는 "1"이라는 문자에 상응 하는 아스키 코드 31H 가 대입된다.

우리는 또 레지스터 사이에 전송하는 방법으로 이런 명령을 사용하였다.


    MOV BL,2

    MOV AH,BH


첫 줄의 명령에 의해 BL 레지스터에 2가 대입되고 둘째 줄의 명령에 의해 BL 레지스터에

저장되었던 내용(2라는 값)이 AH 레지스터에 전송(복사)되었으므로 결국 두 레지스터의

내용은 동일하게 2가 되었다.

레지스터에 직접 수치를 전송하는 경우에는 16비트 레지스터에 000F를 F로 입력하여

전송할 수도 있고, 8비트 레지스터에 같은 수치를 전송하기 위하여 마찬가지로 단지

F만을 입력해도 무방하다.

그러나 하나의 레지스터에서 다른 레지스터로 값을 전송할 때는 반드시 두 레지스터의

크기가 같아야 된다.


    MOV  AH ,BX


이런 명령은 잘못된 것이므로, 에러 메시지가 출력될 것이다.

왜냐하면 BX는 16비트 레지스터이고 AH는 8비트 레지스터이기 때문이다.






8. 프로그램을 끝마치는 방법

필자는 지금까지 프로그램을 끝마치기 위하여 INT 20H 명령을 사용하였다.

그러나 이번 프로그램에서는 그와는 다른 명령이 사용되었다.


    MOV AH,4CH

    INT 21H


INT 21H 명령은 항상 AH 레지스터의 값을 참조하여 구체적인 루틴을 인터럽트하는데,

AH 값이 4CH(16진수 4C, 16진수에 H라는 숫자는 없음)인 경우에는 실행하던 프로그램을

끝내고 도스로 복귀하게 된다.

따라서 이 두 줄의 명령에  의해 디버그 안에서의 프로그램 실행이 끝나는

동시에 INT 20H를 사용한 경우처럼  여전히 디버그 안에 남아 있지 않고 디버그까지도

탈출하여 도스 프롬프트로 나가는 사실을 우리는 이미 확인하였다.

MS-DOS의 INT21H 명령  중에서도 시스템 호출(SYSTEM CALL)인 4CH번째의

루틴은 특수한 명령어로서 프로그램을 끝마치고 OS 레벨로 되돌아가기 위한 명령이다.

MS DOS 상에서 동작하는 프로그램은 모두 마지막에 이 명령을 붙인 다음 프로그램을

끝마치고 OS로 되돌아가지  않으면 안 된다. 이 밖에도 프로그램을 끝마치는

방법이 몇  가지 있지만 이 방법이  가장 안전하므로 프로그램의 마지막에는

반드시 이 명령을 두도록 하자



ID:
PW:

     0 분
     1 분

자유게시판

건강백과 HOME

홈페이지 HOME

조   약     HOME

생활지혜 HOME

서식양식 HOME

법원 전산양식 검색

In Na zum

비공개 HOME

백과넷 포탈 : 건강/법률(메인)/홈피/서식/조약/생활지혜

◁ 2002.9.1.~2021.4.11. ▷

관리자 연락(저작권 의심 신고) : 김병희 010-6204-4973 k8z7@hanmail.net