📄 testvga.asm
字号:
;A program to display a string "Hello new Operation System"
ROW = 5
COLUM = 10
ESCKEY = 1BH
STRINGAD = 100h
STRINGL = 1ch
COLORAD = STRINGAD+20H
COLOR = 7
vgaseg = 0a000h
sequen_ctl = 34ch
graphi_ctl = 3ceh
code segment
assume cs:code
start:
;Normal function
;清屏
mov ax,07c0h
mov ds,ax
mov es,ax
mov cx,0
mov dx,184Fh
mov bh,07
mov ax,600h
int 10h
;设置堆栈段
mov ax,0f00h
mov ss,ax
mov sp,100h
;进入640×480×16色模式
;setmode:
;对640*480*16和320*200*256是标准VGA模式,在各种VGA上都分别为12h和13h
mov ax, 12h
int 10h
;准备调用DispZhC过程
mov si,offset chineseS
mov ax,0
mov bx,0
mov cx,60Eh
;call writePix
;call DispZhC
call DispZhS
stop: nop
jmp stop
;在图形模式下显示指定长度的字符串
;输入参数:
; ds:si 字符串点阵缓冲区的首地址
; ax=y0 字符串第一个字符左上角的Y坐标
; bx=x0 字符串第一个字符左上角的X坐标
; ch=n
; cl=color
;返回值:无
DefDis = 5 ;每两个符号间的默认间距为5个像素
CharWidth = 16 ;默认为16点阵,这也是每个字符的像素宽度
DispZhS proc
push bp
push ax
push bx
push ds
push si
push cx
push dx
mov bp,sp
xor dx,dx
jmp s1
nextChar: ;指向下一个要输出的字符
add si,32
add bx,DefDis+CharWidth
s1:
cmp dh,ch ;是否已经输出了指定个数的字符
je Dones
call DispZhc
inc dh
jmp nextChar
Dones:
pop dx
pop cx
pop si
pop ds
pop bx
pop ax
pop bp
ret
;;进入640×480×16色模式
;setmode:
;;对640*480*16和320*200*256是标准VGA模式,在各种VGA上都分别为12h和13h
;mov ax, 4fh
;mov al,2h
;mov bx,102h
;int 10h
DispZhS endp
;在图形模式下显示一个汉字
;输入参数:
; BX=x0 初始左上角X坐标
; AX=y0 初始左上角Y坐标
; CX=color 其实只是cl表示颜色
; ds:si=buff 字符点阵信息首地址
;返回值:无
DispZhC proc
push si
push bp
push ax
push bx
push cx
push dx
mov bp,sp
xor dx,dx ;dx 当前行
jmp a1
Disp:
inc si
inc si ;指向下一个字
inc dx ;行记数加一
a1:
cmp dx,16 ;当前行为0-15,因为是16*16点阵
je Done
xor cx,cx ;cx 当前列初始化
mov bx,word ptr [si] ;读入一行的点阵信息,一行两个字节表示
DispL:
cmp cx,16
je Disp ;换行
or cx,cx ;清零CF
shl bx,1
jc DispP ;如果当前位是1,显示一个点
inc cx
jmp DispL
DispP:
push ax
push bx
push cx
mov ax,[bp+6]
add ax,dx
mov bx,[bp+4]
add bx,cx
mov cx,[bp+2] ;颜色值在cl中
call writePix
pop cx
inc cx
pop bx
pop ax
jmp DispL
Done:
pop dx
pop cx
pop bx
pop ax
pop bp
pop si
ret
DispZhC endp
;功能:
; 在指定的屏幕位置用指定的颜色画一个点
;入口参数:
; bx = x0 象素在屏幕上的X坐标
; ax = y0 象素在屏幕上的Y坐标
; cl = color 象素的颜色值
writePix proc
linelen = 80 ;640*480*16色模式下一条扫描线占用的字节数=Width/8
;计算象素点的位置
push es
push bp
push dx
push ax
push di
push cx
push bx
mov bp,sp
mov cl,3
shr bx,cl ;X0/8
mov cx,linelen
mul cx
add ax,bx ;至此ax中为像素点的偏移,dx为页号
mov di,ax
;设置映象屏蔽寄存器
mov dx,sequen_ctl
mov al,2
out dx,al
inc dx
mov al,0fh ;四个位面全部充许写
out dx,al
;选择写方式2
mov dx,graphi_ctl
mov al,5
out dx,al
inc dx
mov al,2
out dx,al
;计算屏蔽码,并设置位屏蔽寄存器
dec dx
mov al,8
out dx,al
mov cx,[bp] ;取出X坐标
and cl,7
mov al,80h
shr al,cl
inc dx
out dx,al
;写数据
mov ax,vgaseg ;ES段指向显存地址0a000h
mov es,ax
mov ax,[bp+2] ;取颜色值
mov ah,es:[di] ;读一次使屏蔽寄存器有效
mov es:[di],al ;写入显示存储器
pop bx
pop cx
pop di
pop ax
pop dx
pop bp
pop es
ret
writePix endp
chineseS word 00000h,04008h,037fch,01008h,08208h,06208h,02210h,00910h
word 01120h,020A0h,0E040h,020A0h,02110h,02208h,0240Eh,00804h ;“汉”字的字型信息
scanleng word 100
org 1FEh
endSign db 55h,0AAh
code ends
end start
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -