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
Assembly2010. 1. 5. 01:41


main.asm
-------------------------------------------------------------------
.model large
.386

extern ReadBitCountProc:proc

SegData segment
    v_numbers    word    1345h,0F4h,1123h,1212h,12h
    v_bitCount    byte    5 dup (0)    ; 숫자의 1에 대한 각각의 카운트 저장
    v_sortingNumber word    1345h,0F4h,1123h,1212h,12h    ; 소팅된 자료 입력
    v_key        word    5
SegData ends

SegStack segment stack
    byte 100h dup (?)
SegStack ends

SegCode segment   
    mainProc proc
    assume cs:SegCode, ds:SegData, ss:SegStack
    xor  ax, ax
    push ds
    push ax

    mov  ax, SegData
    mov  ds, ax

    xor  si, si    ; word길이씩 증가하는 배열의 인덱스 초기화
    xor  di, di    ; byte길이씩 증가하는 배열의 인덱스 초기화
L_start:
    mov  dx, v_numbers[si]    ; dx에 데이터 입력
    call ReadBitCountProc   
    mov  v_bitCount[di], dl ; 리턴값을 v_bitCount에 저장

    cmp  si, 8    ; 배열의 끝인가 ?
            ; 인덱스가 0 2 4 6 8일때의 값이므로 마지막 인덱스가 8임..
    jz   L_end
    add  si, 2    ; word 배열 인덱스 증가
    inc  di        ; byte 배열 인덱스 증가
    jmp  L_start   

L_end:
    ;--------------------------------------------------------------------------   
    ;    데이터 버블소팅하기
    ;--------------------------------------------------------------------------
    mov  bx, offset v_sortingNumber
    mov  di, v_key
    dec  di
L_01:
    mov  cx, di
    xor  si, si
L_02:
    mov  ax, [bx][si]
    cmp  ax, [bx][si+2]
    jl   L_end2
    mov  dx, [bx][si+2]
    mov  [bx][si], dx
    mov  [bx][si+2], ax
L_end2:
    add  si, 2
    loop L_02

    dec  di
    cmp  di, 0
    jg   L_01

    ret
    mainProc endp
SegCode ends

    end mainProc





sub.asm
-------------------------------------------------------------------
.model large
.386

SegCode segment   
; dx에 입력된 데이터의 1의 숫자를 세어서 dx에 갯수를 출력하는 프로시져
;
; 입력 dx:카운트 하려는 데이터
; 출력 dx:카운트 값
ReadBitCountProc proc
    push cx
    push ax

    xor  cx, cx   
    xor  ax, ax

    mov  cx, 16    ; word길이를 로테이트 하기위해 16번 카운트 설정
L_rotateNumber:
    rcl  dx, 1    ; 캐리를 포함해서 왼쪽으로 1번 쉬프트
    jc   L_addCount ; 캐리가 발생하면 L_addCount로 이동
    loop L_rotateNumber  ; 캐리가 발생하지 않았으면 L_rotateNumber로 이동
    jmp  L_next     ; cx 카운트가 끝났으면 루프 종료
L_addCount:
    inc  ax         ; 리턴값으로 사용할 임시변수에 1 증가
    loop L_rotateNumber

L_next:   
    mov  dx, ax     ; 최종 카운트 갯수 dx에 저장

    pop  ax
    pop  cx
    ret
ReadBitCountProc endp
SegCode ends

    end

'Assembly' 카테고리의 다른 글

[DOS] Serial 통신  (0) 2010.01.05
[DOS] Queue  (0) 2010.01.05
[DOS] 문자열을 입력받아 끝에 $ 추가해서 출력하기  (0) 2010.01.05
[DOS] 10진수를 출력하는 예제  (0) 2010.01.05
[DOS] 어셈블리에서 클래스 구현  (0) 2010.01.05
Posted by houdinist
Assembly2010. 1. 5. 01:37



.model large
.386

DATSEG  SEGMENT
    INPUT DB  30
DATSEG  ENDS

STACKSEG SEGMENT stack
    db 100h dup (?)
STACKSEG ENDS

CODSEG  SEGMENT
        ASSUME  CS:CODSEG,DS:DATSEG,SS:CODSEG
START: 
    MOV AX,DATSEG
        MOV DS,AX
    MOV DX,OFFSET INPUT
    MOV AH,0AH   
    INT 21H      

    xor bx, bx
    mov bl, INPUT+1
    add bx, 2
    mov INPUT[bx], '$'

    MOV DL,0AH
    MOV AH,02H                      
    INT 21H

    MOV DX,OFFSET INPUT+2    
    MOV AH,09H                      
    INT 21H                         
   
    mov ah, 4ch
    int 21h
CODSEG  ENDS
            
         END START


Posted by houdinist