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   ; Procedure: MAIN

31   MAIN    PROC    FAR

32

33   ; save address to return to DOS

34           PUSH    DS

35           PUSH    0

36

37   ; set up segment register

38           MOV     AX,DSEG

39           MOV     DS,AX

40

41   ; display the message

42           MOV     BX,0001H

43           LEA     DX,MESSAGE

44           MOV     CX,L_MESSAGE

45           MOV     AH,40H

46           INT     21H

47

48   ; return to DOS

49           RET

50

51   ; End of Procedure: MAIN

52   MAIN    ENDP

53

54   ; End of Code Segment

55   CSEG    ENDS

56

57           END     MAIN

프로시저 작성 요령

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

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

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

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

□ DOS로 복귀하라.

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

★ 설명문을 추가한다.

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

;display the message

MOV     BX,0001H

LEA     DX,MESSAGE

MOV     CX,L_MESSAGE

MOV     AH,40H

INT     21H

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

END 지시어 (각 프로그램의 마지막 문장에 위치한다.)

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

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

예) MAIN PROC FAR

…

END MAIN

리스팅의 설정

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

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

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

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

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

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

(1) PAGE 지시어

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

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

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

- 오퍼랜드가 없으면 단지 페이지를 넘기라는 뜻임.

(2) TITLE 지시어

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

예) TITLE DISPLAY

명령어 집합의 지정

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

★ 286이 제공하는 편리한 명령들을 사용하려는 경우 □.286□ 지시어를 사용한다.

예) 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

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

스택, 데이터, 엑스트라 세그먼트: 자료를 저장할 메모리의 공간이며 이를 확보하라고 프로그램이 어셈블러에게 지시함.

★ DB 지시어 (Define Byte)

- DB 지시어에 의해 일정 공간을 데이터 세그먼트에 마련할 수 있다.

예) MESSAGE DB ?

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

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

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

★ 스택으로 사용할 메모리 공간 확보 : DB 지시어를 사용

(1) DB   256 DUP(?)

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

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

(1) 프로그램이 실행될 때 세그먼트 레지스터가 가질 값을 ASSUME 지시어를 사용, 어셈블러에게 알려 주어야 한다.

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

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

- CS, SS레지스터 ∀ 운영체제가 설정함.

- DS, ES레지스터 ∀ (데이터 세그먼트와 엑스트라 세그먼트의 이름이 참조되기 전에) 프로그래머가 설정

예)      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지시어에 의해 엔트리 포인트 설정

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

프로시저의 시작과 끝 : 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

★ 다른 프로그램을 작성할 경우, 이 부분을 새로운 명령어들로 대치하면 됨.

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

TITLE   DISPLAY

.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      AH,40H

INT      21H

RET

MAIN    ENDP

CSEG    ENDS

END      MAIN

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

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

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

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

★ 프로시저 호출할 때 사용하는 명령 : 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           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

호출되는 프로시저의 구조

★ 프로시저의 정의

PROC .... ENDP

★ RET 명령을 사용하여 호출한 프로시저로 복귀

레지스터 값의 저장과 복원

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

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

PUSHA : 세그먼트 레지스터를 제외한 모든 레지스터 값을 저장

- 레지스터의 값을 복원함

POPA : PUSHA 명령이 저장했던 자료를 스택으로 복원

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

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

- DISPM1: 첫째 메시지를 출력

- DISPM2: 둘째 메시지를 출력

★ 다음 페이지 예제 참조

; 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

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

; MAIN (main program)

;

; 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

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

; DISPM1

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

; 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

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

; DISPM2

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

; start of procedure: DISPM2

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

; return to calling program

RET

; 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	메모리 모델을 지정 스택을 설정 데이터 세그먼트를 설정 코드 세그먼트를 설정 주프로그램의 실행 시작을 담당하는 명령들을 생성 주프로그램의 실행을 끝내고 복귀하는데 필요한 명령들을 생성