C H A P T E R

6
ㅔ

어셈블리 언어

프로그램의 이해

공부할 내용

★ 프로토타입 프로그램

- 설명문의 활용

- 리스팅의 설정

- 명령어 집합의 지정

- 세그먼트 설정

- 스택의 확보

- 세그먼트 주소 지정 방식

- 주프로그램의 설정

- 프로시저를 호출하는 프로그램의 설정

- 프로그램 설계를 돕는 지시어의 사용

프로토타입 프로그램

1           PAGE    58,132

2   ;------------------------------------------------

3   ; DISPLAY

4   ;

5   ; Purpose:

6   ;    to display a message on the screen

7   ;------------------------------------------------

8

9   ; set title and instruction set

10           TITLE   DISPLAY - prototype program

11           .286

12

13   ;---------------------------------------- STACK segment

14   SSEG    SEGMENT STACK

15           DB      32 DUP("STACK---")

16   SSEG    ENDS

17

18   ;---------------------------------------- DATA segment

19   DSEG    SEGMENT

20   MESSAGE DB      "Hello, how are you?", 0DH, 0AH

21   L_MESSAGE EQU   $-MESSAGE

22   DSEG    ENDS

23

24   ;---------------------------------------- CODE segment

25   CSEG    SEGMENT  'CODE'

26	ASSUME  CS:CSEG, SS:SSEG, DS:DSEG

27

28           PAGE

29   ;------------------------------------------------

30   ; MAIN (main program)

31   ;

32   ; Purpose:

33   ;    to display a message on the screen

34   ;

35   ; Input:

36   ;    -- none --

37   ;

38   ; Output:

39   ;    the message is displayed on the screen

40   ;

41   ; Procedures:

42   ;    -- none --

43   ;------------------------------------------------

44

45   ; Procedure: MAIN

46   MAIN    PROC    FAR

47

48   ; save address to return to DOS

49           PUSH    DS

50           PUSH    0

51

52   ; set up segment register

53           MOV     AX,DSEG

54           MOV     DS,AX

55

56   ; display the message

57           MOV     BX,0001H

58           LEA     DX,MESSAGE

59           MOV     CX,L_MESSAGE

60           MOV     AH,40H

61           INT     21H

62

63   ; return to DOS

64           RET

65

66   ; End of Procedure: MAIN

67   MAIN    ENDP

68

69   ; End of Code Segment

70   CSEG    ENDS

71

72   ;-------------------------------------- End of program

73           END     MAIN

설명문의 활용

★ 그림 6-1에 있는 프로토타입 프로그램:

73개의 문장 중에서 46(빈 줄을 포함하여)개의 문장이 설명문임.

★ 설명문의 종류

- 2∼7행: 프로그램 자체에 대한 설명

- 29∼43행: 주프로그램에 대한 일반적인 정보

(각 프로시저마다 이러한 종류의 설명문을 달아야 함)

- 9, 13, 18, 24, 45, 48, 52, 56, 63, 66, 69와 72행: 명령/지시어 블록

★ 프로시저 작성 요령

- 우선 프로시저가 할 일을 일상 문장으로 나열하여 본다.

예)  □ DOS로 복귀할 주소를 저장하라.

□ 세그먼트 레지스터를 설정하라.

□ 메시지를 화면에 나타내라.

□ DOS로 복귀하라.

- 이제 각 문장을 여러 줄의 어셈블리 언어로 변환한다.

- 변환된 어셈블리 문장 블록의 앞에 변환되기 전의 영어/한글 문장

을 설명문으로 추가한다.

예)  □메시지를 화면에 나타내라□ 를 다음과 같이 만듬

;display the message

MOV     BX,0001H

LEA     DX,MESSAGE

MOV     CX,L_MESSAGE

MOV     AH,40H

INT     21H

★ 설명문이 옆에 있는 프로토타입 프로그램

PAGE    58,132	; set page size

TITLE   DISPLAY -- prototype program	; set title

.286                               ; 286 instruction set

SSEG    SEGMENT STACK	; begin: stack segment

DB      32 DUP("STACK---")	; define 256 byte stack

SSEG    ENDS	; end: stack segment

DSEG    SEGMENT	; begin: data segment

MESSAGE DB      "Hello, how are you?",0DH,0AH	; message

L_MESSAGE EQU   $-MESSAGE	; length of message

DSEG    ENDS	; end: data segment

CSEG    SEGMENT  'CODE'	; begin: code segment

ASSUME   CS:CSEG, SS:SSEG, DS:DSEG	; define segment regs

MAIN    PROC     FAR	; begin: main program

PUSH     DS	; push DOS return...

PUSH     0	; ...address

MOV      AX,DSEG	; initialize data...

MOV      DS,AX	; ...segment register

MOV      BX,0001H	; set file handle

LEA      DX,MESSAGE	; DX --> message

MOV      CX,L_MESSAGE	; set message length

MOV      AX,40H	; set function 40H

INT      21H	; display the message

RET	; return to DOS

MAIN    ENDP	; end: main program

CSEG    ENDS	; end: code segment

END      MAIN	; end: program

★ 프로그램의 끝을 나타내는 방법

- 각 프로그램의 마지막 문장: END 지시어

(1) 이 지시어는 프로그램의 끝을 나타낸다.

(2) 이 문장의 오퍼랜드는 실행 시작점을 어셈블러에게 알린다.

리스팅의 설정

★ 리스팅(listing): 어셈블러가 프로그램을 처리하면서 생성하는 프린터로 출력하기에 적당한 형태의 보고서

★ 리스팅에 포함되어 있는 것

(1) 프로그램의 각 문장과 그 문장에 대응되는 기계어

(2) 틀린 문장의 경우 에러 메시지를 출력

(3) 프로그램에서 사용하는 각종 이름들에 대한 정보

★ 리스팅을 설정을 위한 지시어들

(1)  PAGE 지시어(1, 28행)

- 오퍼랜드가 있는 경우 리스티의 페이지 길이와 너비를 제어

PAGE    58, 132  (58행 132열을 의미)

- 프로그램의 첫째 줄에 있어야 한다.

- 오퍼랜드가 없으면 단지 페이지를 넘기라는 뜻 (28행)

(2) TITLE 지시어(10행)

- 리스팅의 각 페이지의 윗부분에 출력될 제목 지정

명령어 집합의 지정

★ 어셈블러가 기본적으로 인식하는 명령어들은 8086 명령어 집합이다.

★ 286이 제공하는 편리한 명령들을 사용하려는 경우  .286 (11행)

예) POP과 PUSH 명령에 상수를 사용하거나,

POPA와 PUSHA와 같은 명령을 사용하려 할 때

즉,   PUSH    0      <==>     MOV     AX, 0

PUSH    AX

세그먼트의 설정

★ 대부분의 프로그램에 있는 세그먼트

(1) 스택 세그먼트, (2) 데이터 세그먼트, (3) 코드 세그먼트

가 한 개씩  있다. (이 순서대로)

★ 엑스트라 세그먼트: 데이터 세그먼트와 겹치게 하거나(overlap),

데이터 세그먼트 바로 다음에 둔다.

★ 세그먼트의 설정에 쓰이는 지시어

SEGMENT 지시어 - 세그먼트의 시작을 표시

ENDS 지시어      - 세그먼트의 끝을 표시

(1) 스택 세그먼트

SSEG    SEGMENT STACK

SSEG    ENDS

(2) 데이터 세그먼트

DSEG    SEGMENT

DSEG    ENDS

(3) 코드 세그먼트

CSEG    SEGMENT 'CODE'

CSEG    ENDS

(4) 엑스트라 세그먼트

ESEG    SEGMENT

ESEG    ENDS

★ 세그먼트의 이름: SSEG, DSEG, CSEG와 ESEG 대신에 다른 이름을

선택하여도 된다.

★ 코드 세그먼트를 정의할 때, SEGMENT 지시어의 오퍼랜드로

＋CODE＋를 사용해야 한다.

★ 코드 세그먼트: 명령문이 있는 곳

스택, 데이터, 엑스트라 세그먼트: 자료를 저장할 메모리의 공간이며

이를 확보하라고 프로그램이 어셈블러에게 지시함.

★ DB 지시어 (20행)

- 이러한 공간을 데이터 세그먼트에 마련하도록 한다.

- DB <==> □define byte□

- 확보한 공간에 초기치를 줄 수 있다.

MESSAGE DB      "Hello, how are you?",0DH,0AH

스택으로 사용할 메모리 공간의 확보

★ 스택으로 사용할 메모리 공간의 확보: DB 지시어를 쓴다. (15행)

(1)    DB      256 DUP(?)

=> 256 바이트를 스택 공간으로 확보한다.

(2)    DB      32 DUP("STACK---")

=> 256 바이트를 스택 공간으로 확보한 후에

STACK---STACK---STACK---STACK--- 와 같이

초기값을 주어, 디버거를 사용할 때 화면에 스택의 위치

가 보이도록 한다.

스택, 데이터, 코드 세그먼트의 주소 지정 방식

(1) 프로그래머는 프로그램이 실행될 때 세그먼트 레지스터가 가질 값을

어셈블러에게 알려 주어야 한다. (ASSUME 지시어 사용)

ASSUME  CS:CSEG, SS:SSEG, DS:DSEG

(2) 세그먼트 레지스터가 실제로 그 값을 갖도록 해 주어야 한다.

- 프로그래머는 CS와 SS 레지스터의 값을 설정(set up)할

필요가 없다. DOS가 프로그램을 로드할 때, CS는 코드 세그먼트

의 첫째 바이트가 있는 곳으로, SS는 스택의 첫째 바이트가 있는

곳으로 자동적으로 설정해 준다.

- DS와 ES 레지스터는 프로그래머 자신이 설정해야 한다.

(데이터 세그먼트와 엑스트라 세그먼트의 이름이 참조되기 전에)

(1) DS 레지스터의 설정

데이터 세그먼트의 첫째 바이트의 주소를 DS에 로드함

올바른 방법

; set up segment register

MOV     AX, DSEG

MOV     DS, AX

틀린 방법    MOV     DS, DSEG

(세그먼트 레지스터로 직접 값을 복사할 수 없다)

엑스트라 세그먼트의 주소 지정 방식

★ 엑세트라 세그먼트의 용도

(1) 데이터 세그먼트와는 다른 자료 공간으로 사용됨

ESEG    SEGMENT

ESEG    ENDS

-  이 때, 다음과 같이 ASSUME문으로 설정해야 함.

ASSUME  CS:CSEG, SS:SSEG, DS: DSEG, ES:ESEG

-  DS 레지스터를 설정할 때, ES 레지스터도 함께 설정

; set up segment registers

MOV     AX, DSEG

MOV     DS, AX

MOV     AX, ESEG

MOV     ES, AX

(2) 엑스트라 세그먼트와 데이터 세그먼트가 동일한 메모리 공간을

차지하도록 한다. 이렇게 하면 한 데이터를 참조할 때 데이터

세그먼트에 있는 것처럼 취급할 수도 있고 엑스트라 세그먼트에

있는 것처럼 취급할 수도 있다. (스트링 명령에서 사용)

이렇게 설정하려면,

DSEG    SEGMENT

DSEG    ENDS

ASSUME  CS:CSEG, SS:SSEG, DS:DSEG, ES:DSEG

; set up segment registers

MOV     AX, DSEG

MOV     DS, AX

MOV     ES, AX

주프로그램의 설정

★ 프로그램은 1개 이상의 프로시저로 나뉘어진다.

★ 가장 먼저 실행되는 프로시저가 주프로시저이다(main procedure).

★ 프로시저의 실행이 시작되는 곳의 주소를 □엔트리 포인트(entry

point)□라고 한다. (주프로그램의 엔트리 포인트는 전체 프로그램의

실행이 시작되는 곳이다.)

예)  END MAIN (프로토타입 프로그램의 73행)

★ 모든 프로시저는 코드 세그먼트 내에 있어야 한다.

프로시저의 시작과 끝: PROC과 ENDP 지시어

MAIN    PROC    FAR

MAIN    ENDP

(1) PROC 지시어가 FAR라는 오퍼랜드를 가지면 그 프로시저는

다른 세그먼트로부터 호출된다는 뜻

(MAIN 프로시저: DOS 프로시저에 의하여 호출된다.)

(2) 모든 프로시저의 마지막 명령문은 RET 명령이다. 이 명령은

호출한 프로시저로 복귀하는 명령이다. 주프로그램의 경우

에 RET 명령은 DOS로 복귀하도록 한다.

(RET 명령문: 복귀 주소가 스택에 있다고 가정함)

★  프로그램의 실행이 끝나고 DOS로 돌아갈 곳의 주소를 스택에 저장

; save address to return to DOS

PUSH    DS

PUSH    0

일을 하는 문장들

; display the message

MOV     BX, 0001H

LEA      DX, MESSAGE

MOV     CX, L_MESSAGE

MOV     AH, 40H

INT      21H

★ 다른 프로그램을 작성할 때: 이 부분을 새로운 명령들로 대치하면 됨

프로시저를 호출하는 프로그램의 설정

★ 여러 개의 프로시져가 있는 프로그램의 설정

□ 모든 프로시저는 코드 세그먼트 내에 있어야 한다.

□ 각 프로시저의 시작과 끝을 알리기 위해 PROC과 ENDP를 사용

★ 그림 6-4 참조

★ 프로시저 호출할 때 사용하는 명령: CALL

예) PROC1을 호출하려면

CALL    PROC1

★ 호출한 프로시저로 복귀할 때는

RET

	그림 6-4			프로시저를 호출하는 프로그램의 윤곽

SSEG     SEGMENT STACK

-Stack Segment-

SSEG     ENDS

DSEG     SEGMENT

-Data Segment-

DSEG     ENDS

ESEG     SEGMENT

-Extra Segment-

ESEG     ENDS

CSEG     SEGMENT 'CODE'	□

□

MAIN     PROC     FAR	□

-Main Program-	□

MAIN     ENDP	□

□

PROC1    PROC	□

-Procedure 1-	□ 코드 세그먼트

PROC1    ENDP	□

□

PROC2    PROC	□

-Procedure 2-	□

PROC2    ENDP	□

□

CSEG     ENDS	□

END     MAIN

호출되는 프로시저의 프로토타입

1           PAGE

2   ;---------------------------------------------

3   ; DISPM1

4   ;

5   ; Purpose:

6   ;    to display the first of two messages

7   ;

8   ; Input:

9   ;    -- none --

10   ;

11   ; Output:

12   ;    the message is displayed on the screen

13   ;

14   ; Procedures:

15   ;    -- none --

16   ;---------------------------------------------

17

18   ; start of procedure: DISPM1

19   DISPM1  PROC

20

21   ; save  registers

22     PAGE  PUSHA

23

24   ; display the first message

25           MOV      BX,0001H

26           LEA      DX,MSG1

27           MOV      CX,L_MSG1

28           MOV      AH,40H

29           INT      21H

30

31   ; restore registers

32           POPA

33

34   ; return to calling program

35           RET

36

37   ; End of Procdure: DISPM1

38   DISPM1  ENDP

호출되는 프로시저의 구조

★ 그림 6-5를 참조

- PAGE 지시어 (1행)

어셈블러에게 리스팅 만들 때 새 페이지에서 시작하라고 지시

- 프로시저의 정의: PROC ....  ENDP

- RET 명령을 사용하여 호출한 프로시저로 복귀(35행).

레지스터 값의 저장과 복원

★ 호출되는 프로시저에는 레지스터를 저장하고 복원하는 명령이 있음

- 레지스터의 값을 스택에 저장

PUSHA(□push all□) 명령: 세그먼트 레지스터를 제외한

모든 레지스터의 값을 저장한다.

- 레지스터의 값을 복원함

POPA(□pop all□) 명령: PUSHA 명령이 저장했던 자료를

스택으로 복원함

프로시저를 호출하는 프로그램의 프로토타입

★ 그림 6-6 참조

- DISPLAY  : 화면에 2개의 메시지를 출력한다.

DISPM1: 첫째 메시지를 출력

DISPM2: 둘째 메시지를 출력

PAGE     58,132

;---------------------------------------------

; DISPLAY2

;

; Purpose:

;    to display 2 messages on the screen

;---------------------------------------------

; set title and instruction set

TITLE   DISPLAY2 prototype program, calls procedures

.286

;--------------------------------------------- STACK segment

SSEG    SEGMENT STACK

DB      32 DUP("STACK---")

SSEG    ENDS

;---------------------------------------------	DATA segment

DSEG    SEGMENT

MSG1    DB      "This is message 1",0DH,0AH

L_MSG1  EQU     $-MSG1

MSG2    DB      "This is message 2",0DH,0AH

L_MSG2  EQU     $-MSG2

DSEG    ENDS

;---------------------------------------------	CODE segment

CSEG    SEGMENT  'CODE'

ASSUME   CS:CSEG, SS:SSEG, DS:DSEG

PAGE

;---------------------------------------------

; MAIN (main program)

;

; Purpose:

;    to display 2 messages on the screen

;

; Input:

;   -- none --

;

; Output

;    the messages are displayed on the screen

;

; Procedures:

;    DISPM1  -- display the first message

;    DISPM2  -- display the second message

;---------------------------------------------

; Procedure: MAIN

MAIN   PROC    FAR

; save address to return to DOS

PUSH    DS

PUSH    0

; set up segment registers

MOV     AX,DSEG

MOV     DS,AX

; display the messages

CALL    DISPM1

CALL    DISPM2

; return to DOS

RET

; End of Procedure: MAIN

MAIN   ENDP

PAGE

;---------------------------------------------

; DISPM1

;

; Purpose:

;    to display the first of two messages

;

; Input:

;  -- none --

;

; Output:

;    the message is displayed on the screen

;

; Procedures:

;  -- none --

;---------------------------------------------

; start of procedure: DISPM1

DISPM1  PROC

; save registers

PUSHA

; display the first message

MOV     BX,0001H

LEA     DX,MSG1

MOV     CX,L_MSG1

MOV     AH,40H

INT     21H

; restore registers

POPA

; return to calling program

RET

; End of Procedure: DISPM1

DISPM1  ENDP

PAGE

;---------------------------------------------

; DISPM2

;

; purpose:

;    to display the second of two messages

;

; Input:

;  -- none --

;

; Output:

;    the message is displayed on the screen

;

; Procedures:

;  -- none --

;---------------------------------------------

; start of procedure: DISPM2; DISPM2

;

; purpose:

;    to display the second of two messages

;

; Input:

;  -- none --

;

; Output:

;    the message is displayed on the screen

;

; Procedures:

;  -- none --

;---------------------------------------------

; start of procedure: DISPM2

; return to calling program

RET

DISPM2  PROC

; save registers

PUSHA

; display the first message

MOV     BX,0001H

LEA     DX,MSG2

MOV     CX,L_MSG2

MOV     AH,40H

INT     21H

; restore registers

POPA

; End of Procedure: DISPM2

DISPM2  ENDP

; End of Code Segment

CSEG    ENDS

;---------------------------------------------	End of Assembly

END     MAIN

프로그램 설계를 돕는 지시어의 사용

	표 6-1			프로그램 설계에 사용되는 지시어들

지시어	목적
.MODEL .STACK .DATA .CODE .STARTUP .EXIT	메모리 모델을 지정 스택을 설정 데이터 세그먼트를 설정 코드 세그먼트를 설정 주프로그램의 실행 시작을 담당하는 명령들을 생성 주프로그램의 실행을 끝내고 복귀하는데 필요한 명령들을 생성

	그림 6-7			dot 지시어를 사용하여 다시 쓴 프로토타입 프로그램

PAGE    58,132

;---------------------------------------------

; DISPLAY

;

; Purpose:

;    to display a message on the screen

;---------------------------------------------

; set title, memory model and instruction set

TITLE   DISPLAY -- prototype program

.MODEL  SMALL

.286

; set up the stack

.STACK

;-------------------------------- DATA segment

.DATA

MESSAGE  DB        "Hello, how are you?",0DH,0AH

L_MESSAGE EQU     $-MESSAGE

;-------------------------------- CODE segment

.CODE

PAGE

;---------------------------------------------

; MAIN (main program)

;

; Purpose:

;    to display a message on the screen

;

; Input:

;  -- none --

;

; Output

;    the message is displayed on the screen

;

; Procedures:

;  -- none --

;---------------------------------------------

;

; Procedure: MAIN

MAIN    PROC    FAR

; start the main program

.STARTUP

; display the message

MOV     BX,0001H

LEA     DX,MESSAGE

MOV     CX,L_MESSAGE

MOV     AH,40H

INT     21H

; return to DOS

.EXIT

; end of procedure: MAIN

MAIN    ENDP

;------------------------------ End of program

END

★ .MODEL 지시어

- 프로그램이 사용할 메모리 모델을 지정함

예)   TINY  SMALL  MEDIUM  COMPACT  LARGE

HUGE  FLAT

- 대부분의 프로그램의 경우에는 □small□ 모델이면 된다.

(코드 세그먼트와 데이터 세그먼트가 각각 64K 세그먼트보다 작다)

★ .STACK 지시어

- 스택을 설정한다.

- 스택의 시작과 끝을 정의하고 필요한 공간을 확보한다.

크기가 지정되어 있지 않으면 1024 바이트를 확보한다.

.STACK 256 등으로 크기를 정할 수 있다.

★ .DATA 지시어

-  데이터 세그먼트의 시작을 정의한다.

★ .CODE지시어

-  데이터 세그먼트를 끝내고 코드 세그먼트를 시작한다.

(프로그램에 프로시저가 1개 이상 있다면 각 프로시저마다

.DATA와 .CODE를 사용할 수 있다.)

★ .STARTUP과 .EXIT 지시어

- 주프로그램을 시작하고, 실행이 끝난 후에 운영체제로 복귀하는

명령문들을 생성한다.

★ 프로그램 과정 (첫번째 예제)

PAGE    58,132

TITLE   DISPLAY -- prototype program

.286

SSEG    SEGMENT STACK

DB      32 DUP("STACK---")

SSEG    ENDS

DSEG    SEGMENT

DSEG    ENDS

CSEG    SEGMENT  'CODE'

ASSUME   CS:CSEG, SS:SSEG, DS:DSEG

MAIN    PROC     FAR

MAIN    ENDP

CSEG    ENDS

END      MAIN

PAGE    58,132

TITLE   DISPLAY -- prototype program

.286

SSEG    SEGMENT STACK

DB      32 DUP("STACK---")

SSEG    ENDS

DSEG    SEGMENT

DSEG    ENDS

CSEG    SEGMENT  'CODE'

ASSUME   CS:CSEG, SS:SSEG, DS:DSEG

MAIN    PROC     FAR

PUSH     DS

PUSH     0

MOV      AX,DSEG

MOV      DS,AX

실제 문제에 대한 풀이(코드)가

들어가는 부분

RET

MAIN    ENDP

CSEG    ENDS

END      MAIN

PAGE    58,132

TITLE   DISPLAY -- prototype program

.286

SSEG    SEGMENT STACK

DB      32 DUP("STACK---")

SSEG    ENDS

DSEG    SEGMENT

MESSAGE DB      "Hello, how are you?",0DH,0AH

L_MESSAGE EQU   $-MESSAGE

DSEG    ENDS

CSEG    SEGMENT  'CODE'

ASSUME   CS:CSEG, SS:SSEG, DS:DSEG

MAIN    PROC     FAR

PUSH     DS

PUSH     0

MOV      AX,DSEG

MOV      DS,AX

MOV      BX,0001H

LEA      DX,MESSAGE

MOV      CX,L_MESSAGE

MOV      AX,40H

INT      21H

RET

MAIN    ENDP

CSEG    ENDS

END      MAIN