Assembly2010. 1. 5. 01:44



.MODEL LARGE, STDCALL

.386

;----------------------------------------------------------------------------------------
;    인클루드 선언
;----------------------------------------------------------------------------------------
INCLUDE MyMacro.inc



;----------------------------------------------------------------------------------------
;    프로시져 선언
;----------------------------------------------------------------------------------------
PROC_EnQueue PROTO  :BYTE
PROC_DeQueue PROTO



;----------------------------------------------------------------------------------------
;    퍼블릭 선언
;----------------------------------------------------------------------------------------
PUBLIC Queue                ; 외부에서 큐 내용을 참조할 수 있도록 공개



;----------------------------------------------------------------------------------------
;    상수 선언
;----------------------------------------------------------------------------------------
QUEUE_MAX_BUFFER    EQU    4    ; 최대 큐 버퍼 사이즈
Debug            EQU    1    ; 1 -> 디버깅 내용 출력, 0 -> 디버깅 내용 출력 안함



;----------------------------------------------------------------------------------------
;    데이터 세그먼트
;----------------------------------------------------------------------------------------
QUEUE_DATASEG SEGMENT
    Queue            db    4 dup('x')    ; 실제 큐
    QueueSize        db    0        ; 큐 사용량
    TempPos            db    0        ; 가상 인덱스
    Position        db    0        ; 실제 인덱스
    StrBufferOverFlow    db    'Buffer Overflow', 0Ah, 0Dh
    BufferUnderFlow        db    'Buffer Underflow', 0Ah, 0Dh
    strDeQueueText        db    'DeQueue Value = '
QUEUE_DATASEG ENDS



;----------------------------------------------------------------------------------------
;    스택 세그먼트
;----------------------------------------------------------------------------------------
QUEUE_STACK SEGMENT STACK
    DB    100h    DUP('stack')
QUEUE_STACK ENDS



;----------------------------------------------------------------------------------------
;    코드 세그먼트
;----------------------------------------------------------------------------------------
QUEUE_CODE SEGMENT PARA 'CODE'

    ;-------------------------------------------------------------------
    ;
    ;    큐에 값 하나를 넣는다.
    ;   
    ;    인자 : MyValue:BYTE
    ;    리턴 :
    ;
    ;-------------------------------------------------------------------
    ASSUME CS:QUEUE_CODE, DS:QUEUE_DATASEG, SS:QUEUE_STACK
START:
    PROC_EnQueue PROC MyValue:BYTE
        pusha
       
        mov ax, QUEUE_DATASEG        ;
        mov ds, ax            ; 데이터 세그먼트 설정


        cmp QueueSize, QUEUE_MAX_BUFFER    ; 현재버퍼크기 >= 최대버퍼크기
        jge LABEL_BufferFull        ; 버퍼가 꽉 찻으므로 종료

        cmp Position, QUEUE_MAX_BUFFER    ;
        jl  LABEL_PositionNext        ; 데이터인덱스 < 최대버퍼크기
        mov Position, 0            ; Postion = 0

    LABEL_PositionNext:

        mov ah, Position        ;----------------------------------
        mov al, QueueSize        ; TempPos = Position + QueueSize
        add ah, al            ;
        mov TempPos, ah            ;----------------------------------

        cmp TempPos, QUEUE_MAX_BUFFER    ;
        jl  LABEL_TempPosChange        ; TempPos < 최대버퍼크기
        sub TempPos, QUEUE_MAX_BUFFER    ; TempPos = TempPos - 최대버퍼크기

    LABEL_TempPosChange:
       
        mov ah, MyValue            ;----------------------------------        
        xor bx, bx            ; 지정된 위치에 데이터 넣기
        mov bl, byte ptr TempPos    ;
        mov Queue[bx], ah        ;----------------------------------
       
        inc QueueSize            ; 현재버퍼크기 1 증가
    LABEL_Exit:
   
        ;----------------------------------------------------------------------
        ; Debugging Text -> 큐 전체 내용을 찍는다.
        IF Debug
            ShowAllQueueDebugString
        ENDIF       
        ; Debugging Text End
        ;----------------------------------------------------------------------

        popa
        ret

    LABEL_BufferFull:
       
       
        mov ax , QUEUE_DATASEG
        mov ds , ax
        mov dx , OFFSET StrBufferOverFlow
        mov cx , SIZEOF StrBufferOverFlow
        xor bx , bx   ;consol handle = 0
        mov ah , 40h
        int 21h

        NextLine
            ;
       
        popa
        ret
    PROC_EnQueue ENDP

    ;-------------------------------------------------------------------
    ;
    ;    큐에서 값 하나를 꺼낸다.
    ;   
    ;    인자 :
    ;    리턴 : DL -> 큐에서 꺼낸 값
    ;
    ;-------------------------------------------------------------------
    PROC_DeQueue PROC
        push ax                ;-----------------------------
        push ds                ; 레지스터 보호
        push bx                ; ax, ds, bx, si, cx
        push si                ;
        push cx                ;-----------------------------
       
               
        mov ax, QUEUE_DATASEG        ;
        mov ds, ax            ; 데이터 세그먼트 초기화
       
        cmp QueueSize, 0        ;
        jz  LABEL_BufferEmpty        ; 큐에 내용이 없으면 Buffer UnderFlow

        xor bx, bx            ;
        mov bl, byte ptr Position    ; 가져 올 값의 인덱스 구하기 -> BL
               

        ;----------------------------------------------------------------
        ; Debugging Text -> 꺼낸 값 하나를 찍는다.
        ;       
        IF Debug
            DeQueueValueDebugString QUEUE_DATASEG, strDeQueueText
        ENDIF
        ; Debugging Text End
        ;-----------------------------------------------------------------
       
        mov dl, Queue[bx]        ; 구한 인덱스릐 큐 값을 DL에 넣는다. -> DL
        mov Queue[bx], 'x'        ; 값을 빼고 빈자리에 'x'를 넣는다.

        inc Position            ; 인덱스를 다음 값의 위치로 셋팅
        dec QueueSize            ; 큐 사이즈를 하나 줄인다.


        ;-----------------------------------------------------------------
        ; Debugging Text -> 큐 전체 내용을 찍는다.
        IF Debug
            ShowAllQueueDebugString
        ENDIF
        ; Debugging Text End   
        ;-----------------------------------------------------------------

        pop cx                ;---------------------------------
        pop si                ; 레지스터 복원
        pop bx                ; cx, si, bx, ds, ax
        pop ds                ;
        pop ax                ;---------------------------------
               
        ret

    LABEL_BufferEmpty:
       
        mov ax , QUEUE_DATASEG
        mov ds , ax
        mov dx , OFFSET BufferUnderFlow
        mov cx , SIZEOF BufferUnderFlow
        xor bx , bx   ;consol handle = 0
        mov ah , 40h
        int 21h

        NextLine



        pop cx                ;---------------------------------
        pop si                ; 레지스터 복원
        pop bx                ; cx, si, bx, ds, ax
        pop ds                ;
        pop ax                ;---------------------------------
               

        ret
    PROC_DeQueue ENDP   

   
QUEUE_CODE ENDS

END START
       

Posted by houdinist