組合語言實現圖形繪製——矩形、三角形等
組合語言實現圖形繪製
一、準備工作
1.INT 10H的功能
INT 10H 是由 BIOS 對螢幕及顯示器所提供的服務程式。使用 INT 10H 中斷服務程式時,先指定 AH 暫存器編,該編號表示欲呼叫的功用,然後再定義其它暫存器內容,當一切設定好之後再呼叫 INT 10H。下面是我們在程式中用到的指令:
AH=00H
AH=00/INT 10H 是用來設定顯示模式的服務程式,AL 暫存器表示欲設定的模式
;AL部分模式說明 mov al,12h ;640*480 256的圖形模式: mov al,13h ;320*200 256色的圖形模式: ;完整呼叫 mov al,13h ;320*200 256色的圖形模式: mov ah,0 ;是用來設定顯示模式的服務程式 int 10h
AH=0CH
AH=0Ch/INT 10H 是在繪圖模式中顯示一點 ( 也就是寫入點像),而 AH=0DH/INT 10H 則是讀取點像。
寫入時,要寫入位置 X 座標存於 CX 暫存器,Y 座標存於 DX 暫存器,顏色存於 AL 暫存器。對於彙編的顯示視窗,左上角為原點,向右為X軸,越往右X數值越大;向下為Y軸,越往下Y數值越大。X、Y座標的邊界以及顏色的種類則和之前定義的顯示模式相關。
顯示模式 | X 座標 | Y 座標 | 顏色 |
4 | 0~319 | 0~199 | 0、1 |
5 | 0~319 | 0~199 | 0~3 |
6 | 0~639 | 0~199 | 0、1 |
AH=0DH/INT 10H 則是讀取某一位置之點像,您必須指定 CX、DX,而 INT 10H 會傳回該位置點像之顏色。
;完整呼叫
mov cx,10 ;x座標
mov dx,10 ;y座標
mov al,1100b ;淡紅色
mov ah,0ch ;寫入點像
int 10h ;呼叫中斷
二進位制數 | 顏色 | 例子 | 二進位制數 | 顏色 | 例子 |
0000 | 黑色 | black | 1000 | 灰色 | gray |
0001 | 藍色 | blue | 1001 | 淡藍色 | light blue |
0010 | 綠色 | green | 1010 | 淡綠色 | light green |
0011 | 青色 | cyan | 1000 | 淡青色 | light cyan |
0100 | 紅色 | red | 1100 | 淡紅色 | light red |
0101 | 紫紅色 | magenta | 1101 | 淡紫紅色 | light magenta |
0110 | 棕色 | brown | 1110 | 黃色 | yellow |
0111 | 銀色 | light gray | 1111 | 白色 | white |
2.Bresenham直線演算法
對於直線、豎線的繪製,方法比較簡單
而對於斜線的繪製,則存在一些問題。因為我們的螢幕是由畫素點構成,而畫素點的座標都是整數,但是在直線上每一點的座標不一定是整數,所以我們將要對該點進行近似處理,選取螢幕上最接近該點的畫素點進行繪製。
Bresenham直線演算法就是用來描繪由兩點所決定的直線的演算法,它會算出一條線段在 n 維光柵上最接近的點。這個演算法只會用到較為快速的整數加法、減法和位元移位,常用於繪製電腦畫面中的直線。是計算機圖形學中最先發展出來的演算法。
我們以0<K<1的斜線為例:
若圖,該演算法的核心思想:
當前點為A(X,Y),由於K的限制性,下一個繪製的點為B(X+1,Y)或者C(X+1,Y+1)。而直線上的點為C點,該點介於B點和D點之間,所以我麼就要判斷C點是偏向於B點還是D點。其中一種方法是將(X+1,Y+1/2)帶入直線方程F中:
若F(X+1,Y+1/2)> 0,則證明B、D之間的中點在直線上方,則選取B點為下一個繪製的畫素點。
若F(X+1,Y+1/2)< 0,則證明B、D之間的中點在直線下方,則選取D點為下一個繪製的畫素點。
在知道核心思想之後,為了提高執行效率,該演算法通過一系列複雜的數學公式簡化了運算方式(有興趣的同學可以去了解一下),只會用到較為快速的整數加法、減法和位元移位就能完成上述操作,最終運算結果如下:
對於直線y=kx+b(已知兩點(x1,y1)(x2,y2),設y2>y1,△y=y2-y1,△x=|x2-x1|)
推導過程:
P=△y-1/2 = f(x+1)-f(x)-1/2= kx+k-kx-1/2=k-1/2=△y/△x - 1/2 為了簡化運算,兩邊同乘2△x,由於我們只需要看左邊符號,所以忽略△x,最終結果如下:
P=2△y-△x
1、0<K<1(X+1,判斷Y)
Pn=2△y-△x
若Pn < 0,下一個繪製點為(X+1,Y),Pn+1=Pn+2△y
若Pn >= 0,下一個繪製點為(X+1,Y+1),Pn+1=Pn+2(△y-△x)
2、K>1(Y+1,判斷X)
Pn=2△y-△x
若Pn < 0,下一個繪製點為(X,Y+1),Pn+1=Pn+2△x
若Pn >= 0,下一個繪製點為(X+1,Y+1),Pn+1=Pn+2(△x-△y)
3、-1<K<0(X-1,判斷Y)
Pn=2△y-△x
若Pn < 0,下一個繪製點為(X-1,Y),Pn+1=Pn+2△y
若Pn >= 0,下一個繪製點為(X-1,Y+1),Pn+1=Pn+2(△y-△x)
4、K<-1(Y+1(y2>y1),判斷X)
Pn=2△y-△x
若Pn < 0,下一個繪製點為(X,Y+1),Pn+1=Pn+2△x
若Pn >= 0,下一個繪製點為(X-1,Y+1),Pn+1=Pn+2(△x-△y)
二、程式碼實現
1、直線
;橫線
;mov al,12h ;640*480 256的圖形模式:
mov al,13h ;320*200 256色的圖形模式:
mov ah,0 ;是用來設定顯示模式的服務程式
mov cx,10 ;x座標
mov bx,100 ;終止x座標
mov dx,10 ;y座標
int 10h
pheng:
mov al,1100b ;淡紅色
mov ah,0ch ;寫入點像
inc cx
cmp cx,bx
int 10h
jne pheng
執行結果:
2、豎線
;豎線
;mov al,13h ;320*200 256色的圖形模式:
;mov ah,0 ;是用來設定顯示模式的服務程式
mov cx,10 ;x座標
mov bx,100 ;終止x座標
mov dx,10 ;y座標
;int 10h
pshu:
mov al,1100b ;淡紅色
mov ah,0ch ;寫入點像
inc dx
cmp dx,bx
int 10h
jne pshu
執行結果:
3、斜線
mov al,13h ;320*200 256色的圖形模式:
mov ah,0 ;是用來設定顯示模式的服務程式
int 10h
mov x1,20
mov x2,70
mov y1,10
mov y2,200
mov ax,x2
mov bx,x1
cmp ax,bx
jae dpos1
sub bx,ax
mov s1,-1
mov xd,bx
jmp d1
dpos1:
sub ax,bx
mov s1,1
mov xd,ax
d1:
mov ax,y2
mov bx,y1
cmp ax,bx
jae dpos2 ;y2>=y1
sub bx,ax ;y2<y1
mov s2,-1
mov yd,bx
jmp d2
dpos2:
sub ax,bx
mov s2,1
mov yd,ax
d2:
add ax,ax
mov bx,xd
sub ax,bx
mov p,ax ;2dy-dx
mov cx,x1
mov dx,y1
pxie:
mov al,1100b ;淡紅色
mov ah,0ch ;寫入點像
int 10h
mov ax,p
mov bx,0
cmp ax,bx
jge ppos ;p>=0
jl pneg ;p<0
ppos:
mov ax,xd
mov bx,yd
cmp ax,bx
ja ddpos1 ;xd>yd
jbe ddneg1 ;xd<=yd
ddpos1: ;0<k<1 或者 -1<k<0 同時 p>=0
mov ax,x1 ;x=x+1
mov bx,s1
add ax,s1
mov x1,ax
mov ax,s2 ;y=y+1
mov bx,y1
add bx,ax
mov y1,bx
mov ax,p ;Pn+1=Pn+2(dy-dx)
mov bx,xd
mov cx,yd
add bx,bx
add cx,cx
sub cx,bx
add ax,cx
mov p,ax
jmp plot
ddneg1: ;k>1 或者 k<-1 同時 p>=0
mov ax,y1 ;y=y+1
inc ax
mov y1,ax
mov ax,s1 ;x=x+1 或者 x=x-1
mov bx,x1
add bx,ax
mov x1,bx
mov ax,p ;Pn+1=Pn+2(dx-dy)
mov bx,xd
mov cx,yd
add bx,bx
add cx,cx
sub bx,cx
add ax,bx
mov p,ax
jmp plot
pneg:
mov ax,xd
mov bx,yd
cmp ax,bx
ja ddpos2 ;xd>yd
jbe ddneg2 ;xd<=yd
ddpos2: ;0<k<1 或者 -1<k<0 同時 p<0
mov ax,x1 ;x=x+1
mov bx,s1
add ax,s1
mov x1,ax
mov ax,p ;Pn+1=Pn+2dy
mov bx,yd
add bx,bx
add ax,bx
mov p,ax
jmp plot
ddneg2: ;k>1 或者 k<-1 同時 p<0
mov ax,y1 ;y=y+1
inc ax
mov y1,ax
mov ax,p ;Pn+1=Pn+2dx
mov bx,xd
add bx,bx
add ax,bx
mov p,ax
jmp plot
plot:
mov cx,x1 ;X座標
mov dx,y1 ;Y座標
cmp cx,x2 ;是否繪圖完畢
jne pxie
執行結果:
由於解析度較低,所以斜線比較粗糙
根據上述程式即可完成三角形、矩形等圖形的繪製:
將上述程式封裝為子程式,三角形即可呼叫兩次斜線子程式,一次橫線子程式完成繪製;矩形可呼叫兩次橫線、兩次豎線子程式完成繪製。
在繪製等邊三角形時,由於等邊三角形具有其特殊性,所以在程式碼方面可存在一定優化,如果感興趣可看下篇文章。