;刚学完汇编,练练手而已,高手们别笑我啊
;用emu8086编译器来生成exe文件,然后打开生成的exe文件,在全屏下观看效果
;----------------------------------------------------------
.model small
.stack
.data
circle0 db 6,28,14,52    ;上边界,左边界,下边界,右边界
        db 6,40         ;将要在该位置显示字符
        db 0            ;字符所在位置的方向属性
                        ;逆时针:0左 1下 2右 3上
                        ;顺时针:0右 1下 2左 3上
        db 17           ;将要显示的字符
circle1 db 7,31,13,49    ;
        db 7,40         ;
        db 0            ;
        db 16           ;
circle2 db 8,34,12,46    ;
        db 8,40         ;
        db 0            ;
        db 17           ;
circle3 db 9,37,11,43    ;
        db 9,40         ;
        db 0            ;
        db 16           ;
cirlen EQU circle1-circle0
contrl db 01001010B    ;bit7:    0程序不退出 1程序退出
                        ;bit6:    0静止显示 1动态显示
                        ;bit5与bit4未定义
                        ;bit3:    1表示圈3为顺时针方向
                        ;bit2:    0表示圈2为逆时针方向
                        ;bit1:    1表示圈1为顺时针方向
                        ;bit0:    0表示圈0为逆时针方向
prompt db 'Enter to start or pause, Esc to exit$'
author db 'made by wujungang$'
old_ip09 dw ?
old_cs09 dw ?
.code
SETPOS MACRO OPR1,OPR2
PUSH DX
PUSH BX
PUSH AX
MOV DH,OPR1
MOV DL,OPR2
MOV BH,0
MOV AH,2
INT 10H
POP AX
POP BX
POP DX
ENDM
main proc far
start:
mov ax,@data
mov ds,ax
;============================隐藏光标============================
push cx
push ax
mov ch,00010000B
mov cl,00000000B
mov ah,1
int 10h
pop ax
pop cx

call init
;============================设置键盘中断============================
;save old interrupt 09h
mov al,09h
mov ah,35h
int 21h
mov old_cs09,es
mov old_ip09,bx
push ds
;set new interrupt 09h
lea dx,kbdint
mov ax,seg kbdint
mov ds,ax
mov al,09h
mov ah,25h
int 21h
pop ds
;set keyboard interrupt mask bits
in al,21h
and al,0fdh
out 21h,al
sti
;============================循环显示============================
disp:
test contrl,10000000B
jnz exit
call dispall
test contrl,01000000B
jz disp
call procpos
jmp disp
;============================安全出口============================
exit:
cli
;restore old interrupt 09h
push ds
mov dx,old_ip09
mov ax,old_cs09
mov ds,ax
mov al,09h
mov ah,25h
int 21h
pop ds
;enable keyboard interrupt
in al,21h
and al,0fdh
out 21h,al
sti
;============================结束返回============================
mov ax,4c00h
int 21h
main endp
;-------------------------------------------------------
init proc near
push dx
push ax
SETPOS 2,20
lea dx,prompt
mov ah,09h
int 21h
SETPOS 22,60
lea dx,author
mov ah,09h
int 21h
SETPOS 10,40
mov dl,1
mov ah,2
int 21h
pop ax
pop dx
init endp
;--------------------------------------------------------
dispchar proc near
push ax
push bx
push cx
mov cx,4
lea bx,circle0
loopcir:
SETPOS [bx+4],[bx+5]
mov dl,[bx+7]
mov ah,2
int 21h
add bx,cirlen
loop loopcir
pop cx
pop bx
pop ax
ret
dispchar endp
;---------------------------------------------------------
dispblk proc near
push ax
push bx
push cx
mov cx,4
lea bx,circle0
lopcir:
SETPOS [bx+4],[bx+5]
mov dl,20h
mov ah,2
int 21h
add bx,cirlen
loop lopcir
pop cx
pop bx
pop ax
ret
dispblk endp
;------------------------------------------------------------
dispall proc near
push si
push di
call dispchar
mov si,9000
loop1:
mov di,9000
loop2:
dec di
jnz loop2
dec si
jnz loop1
call dispblk
mov si,9000
loop3:
mov di,9000
loop4:
dec di
jnz loop4
dec si
jnz loop3
pop di
pop si
ret
dispall endp
;---------------------------------------------------------
kbdint proc near
push ax
in al,60h
push ax
in al,61h
mov ah,al
or al,80h
out 61h,al
xchg ah,al
out 61h,al
pop ax
test al,80h
jnz return1
;根据扫描码判断按键
cmp al,01h
je forEsc
cmp al,1ch
je forEnter
jmp return1
forEsc:
or contrl,10000000B
jmp return1
forEnter:
xor contrl,01000000B
return1:
mov al,20h
out 20h,al
pop ax
iret
kbdint endp
;------------------------------------------------------------