.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
'Assembly' 카테고리의 다른 글
[DOS] 마우스로 스프라이트 움직이기 (0) | 2010.01.05 |
---|---|
[DOS] Serial 통신 (0) | 2010.01.05 |
[DOS] 각 숫자의 on된 비트수 세기와 버블 소팅 (0) | 2010.01.05 |
[DOS] 문자열을 입력받아 끝에 $ 추가해서 출력하기 (0) | 2010.01.05 |
[DOS] 10진수를 출력하는 예제 (0) | 2010.01.05 |