⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tuxing.asm

📁 直线、圆等图形函数的汇编语言实现 本例所用的绘图函数均采用堆栈的方法传递参数
💻 ASM
字号:
 				直线、圆等图形函数的汇编语言实现
						
						向远

	本例所用的绘图函数均采用堆栈的方法传递参数,可以和C语言接口。画点的函数采用直接写显存的方法。为了直接由CPU数据确定像素颜色,而不使用位屏蔽寄存器或置位/重置寄存器,采用了VGA的写模式2方式。直线和圆的算法均采用Bresenham算法实现,其实现过程及堆栈状态均有较详细的说明。最后,将绘图函数用宏封装了起来,便于主程序中调用。当然,主程序中也可直接将参数压入堆栈。其实在较高版本的编译程序中,可以用PROTO伪指令定义函数原型,再用INVOKE伪指令调用。

	注:本程序在WIN98系统下由MASM5.0编译通过,XP下好象不行。

.MODEL SMALL
.386
.STACK 100
.DATA 
COLOR DW 02
BKCOLOR DW 15
RADIUS DW 45
;画点宏
MPIXEL MACRO X,Y,COLOR
	PUSH X
	PUSH Y
	PUSH COLOR
	CALL PIXEL
ENDM

;画线宏
MLINE MACRO X1,Y1,X2,Y2
	PUSH X1
	PUSH Y1
	PUSH X2
	PUSH Y2
	CALL LINE
ENDM

;画矩形宏
MRECTANGLE MACRO X1,Y1,X2,Y2
	MLINE X1,Y1,X1,Y2
	MLINE X1,Y1,X2,Y1
	MLINE X2,Y1,X2,Y2
	MLINE X1,Y2,X2,Y2
ENDM

;画圆宏
MCIRCLE MACRO X,Y,R
	PUSH X
	PUSH Y
	PUSH R
	CALL CIRCLE
ENDM

.CODE
MAIN PROC FAR
START:  MOV AX,@DATA
	MOV DS,AX
	MOV AX,0A000H
	MOV ES,AX

	MOV AX,0012H
	INT 10H			;设置640*480*16图形模式

	MOV AL,2
	CALL SET_WRITE_MODE	;将写模式设为写模式2

	MOV AX,BKCOLOR
	CALL CLEAR		;将背景清成白色

	MLINE 100,100,150,150
	MLINE 300,100,250,150
	MLINE 100,300,150,250	;采用宏

	PUSH 300
	PUSH 300
	PUSH 250
	PUSH 250
	CALL LINE		;直接调用画线函数

	MRECTANGLE 100,100,300,300
	MRECTANGLE 150,150,250,250
	MCIRCLE 200,200,RADIUS

	MOV AH,01H
	INT 21H
	MOV AX,4C00H
	INT 21H
MAIN ENDP

;******************************************
;640*480*16模式下的画点函数
;******************************************
PIXEL PROC
	PUSH BP
	PUSH BX
	PUSH CX
	PUSH DS
	MOV BP,SP
	MOV AX,80
	MOV BX,WORD PTR[BP+12]	;BX<=Y
	MUL BX			;(DX:AX)<=80*Y
	MOV BX,AX		;
	MOV AX,WORD PTR[BP+14]	;AX<--X
	MOV CL,8		;				|	 |
	DIV CL			;AL<=商(X/8),AH<=余数(X%8) SP->	|	 |
	MOV CL,AH		;CL<=AH				|   DS	 |<-BP
	MOV AH,0		;				|   CX	 |<-BP+2
	ADD BX,AX		;BX(OFFSET)<=80*Y+X/8		|   BX	 |<-BP+4
	MOV AL,80H		;				|   BP	 |<-BP+6
	SHR AL,CL		;AL(MASK)<=(80H>>CL)		|返回地址|<-BP+8	
	PUSH AX			;				| COLOR	 |<-BP+10
	MOV DX,3CEH		;				|   Y	 |<-BP+12
	MOV AL,8		;				|   X	 |<-BP+14
	OUT  DX,AL		;				|	 |
	MOV DX,3CFH		;			       PIXEL堆栈结构
   	POP AX
	OUT DX,AL
	MOV AL,ES:[BX]
	MOV AX,WORD PTR[BP+10]	;AX<=COLOR
	MOV BYTE PTR ES:[BX],AL
	POP DS
	POP CX
	POP BX
	POP BP
        RET 6
PIXEL ENDP

;******************************************
;Bresenham算法实现的画线函数
;******************************************
LINE PROC NEAR
	PUSH BP
	MOV BP,SP
	SUB SP,16
	MOV WORD PTR[BP-6],0	;X=0
	MOV WORD PTR[BP-8],0	;Y=0
	MOV WORD PTR[BP-14],1	;INCX=1
	MOV WORD PTR[BP-16],1	;INCY=1
	MOV AX,WORD PTR[BP+6]	;AX<=X2
	SUB AX,WORD PTR[BP+10]	;AX<=X2-X1
	JNC L1			;IF X2>=X1,JMP L1		
	NEG AX			;IF X2<X1,DELTA_X=-DELTA_X	
	MOV WORD PTR[BP-14],-1	;INCX<=-1			
L1:	CMP AX,0		;IF DELTA_X!=0,JMP L11		
	JNE L11			;				
	MOV WORD PTR[BP-14],0	;INCX<=0			
L11:	MOV WORD PTR[BP-10],AX	;DELTA_X<=AX		   SP->	|	 |
	MOV AX,WORD PTR[BP+4]	;AX<=Y2			   	|  INCY	 |
	SUB AX,WORD PTR[BP+8]	;AX<=Y2-Y1			|  INCX	 |<-BP-14
	JNC L2			;IF Y2>=Y1,JMP L2		| DELTA_Y|<-BP-12	
	NEG AX			;IF Y2<Y1,DELTA_Y=-DELTA_Y	| DELTA_X|<-BP-10
	MOV WORD PTR[BP-16],-1	;INCY<=-1			|   Y	 |<-BP-8
L2:	CMP AX,0		;IF DELTA_Y!=0,JMP L22		|   X	 |<-BP-6
	JNE L22			;				|DISTANCE|<-BP-4
	MOV WORD PTR[BP-16],0	;INCY<=0			|   T	 |<-BP-2
L22:	MOV WORD PTR[BP-12],AX	;DELTA_Y<=AX			|   BP	 |<-BP
LP4:	MOV AX,WORD PTR[BP-10]	;AX<=DELTA_X			|返回地址|<-BP+2	
	CMP AX,WORD PTR[BP-12]	;				|   Y2	 |<-BP+4
	JG LP5			;DELTA_X>DELTA_Y		|   X2	 |<-BP+6 
	MOV AX,WORD PTR[BP-12]	;				|   Y1	 |<-BP+8
	MOV WORD PTR[BP-4],AX	;DISTANCE<=DELTA_Y		|   X1	 |<-BP+10
	JMP LP51		;				|	 |
LP5:	MOV AX,WORD PTR[BP-10]	;				LINE堆栈结构
	MOV WORD PTR[BP-4],AX	;DISTANCE<=DELTA_X
LP51:	INC AX
	MOV WORD PTR[BP-2],AX
LP6:	PUSH WORD PTR[BP+10]
	PUSH WORD PTR[BP+8]
	PUSH COLOR
	CALL PIXEL
	MOV AX,WORD PTR[BP-6]	;AX<=X
	ADD AX,WORD PTR[BP-10]	;AX<=X+DELTA_X
	MOV WORD PTR[BP-6],AX	;X=X+DELTA_X
	MOV AX,WORD PTR[BP-8]	;AX<=Y
	ADD AX,WORD PTR[BP-12]	;AX<=Y+DELTA_Y
	MOV WORD PTR[BP-8],AX	;Y=Y+DELTA_Y
	MOV AX,WORD PTR[BP-6]	;AX<=X
	CMP AX,WORD PTR[BP-4]
	JLE LP7			;IF X<=DISTANCE,JMP LP7
	MOV AX,WORD PTR[BP-6]	;X>DISTANCE
	SUB AX,WORD PTR[BP-4]	;AX<=X-DISTANCE
	MOV WORD PTR[BP-6],AX	;X=X-DISTANCE
	MOV AX,WORD PTR[BP+10]	;AX<=X1
	ADD AX,WORD PTR[BP-14]	;AX<=X1+INCX
	MOV WORD PTR[BP+10],AX	;X1=X1+INCX
LP7:	MOV AX,WORD PTR[BP-8]	;AX<=Y
	CMP AX,WORD PTR[BP-4]	
	JLE LP8			;IF Y<=DISTANCE,JMP LP8
	MOV AX,WORD PTR[BP-8]	;Y>DISTANCE
	SUB AX,WORD PTR[BP-4]	;AX<=Y-DISTANCE
	MOV WORD PTR[BP-8],AX	;Y=Y-DISTANCE
	MOV AX,WORD PTR[BP+8]	;AX<=Y1
	ADD AX,WORD PTR[BP-16]	;AX<=Y1+INCY
	MOV WORD PTR[BP+8],AX	;Y1=Y1+INCY
LP8:	DEC WORD PTR[BP-2]	;IF T!=0,JMP LP6
	JZ LP9
	JMP LP6
LP9:	MOV SP,BP
	POP BP
	RET 8
LINE ENDP

;***************************************
;Bresenham算法实现的画圆函数
;***************************************
CIRCLE PROC NEAR
	PUSH BP
	MOV BP,SP
 	SUB SP,6
	MOV WORD PTR[BP-2],0	;X<=0			|	 |	
	MOV AX,WORD PTR[BP+4]	;			|	 |
	MOV WORD PTR[BP-4],AX	;Y<=R		   SP->	|	 |
	MOV AX,-2		;			|   P	 |<-BP-6
	IMUL WORD PTR[BP+4]	;AX<=RADIUS*(-2)	|   Y	 |<-BP-4
	ADD AX,3		;AX<=3-2*RADIUS		|   X	 |<-BP-2
	MOV WORD PTR[BP-6],AX	;P=3-2*RADIUS		|   BP	 |<-BP
C0:	MOV AX,WORD PTR[BP-2]	;AX<=X			|返回地址|<-BP+2	
	CMP AX,WORD PTR[BP-4]	;IF X<Y,JMP C00		| RADIUS |<-BP+4	
	JL C00			;			|   YC	 |<-BP+6	
	JMP C3			;			|   XC	 |<-BP+8
C00:	PUSH WORD PTR[BP+8]	;		       CIRCLE堆栈结构	
	PUSH WORD PTR[BP+6]	;
	PUSH WORD PTR[BP-2]	
	PUSH WORD PTR[BP-4]	
	CALL CIRCLE_POINT	
	CMP WORD PTR[BP-6],0	
	JGE C1			
	MOV AX,4		
	MUL WORD PTR[BP-2]	
	ADD AX,6
	ADD AX,WORD PTR[BP-6]
	MOV WORD PTR[BP-6],AX
	JMP C2
C1:	MOV AX,WORD PTR[BP-2]
	SUB AX,WORD PTR[BP-4]
	MOV BX,4
	IMUL BX
	ADD AX,10
	ADD AX,WORD PTR[BP-6]
	MOV WORD PTR[BP-6],AX
	DEC WORD PTR[BP-4]
C2:	INC WORD PTR[BP-2]
	JMP C0
C3:	MOV AX,WORD PTR[BP-2]
	CMP AX,WORD PTR[BP-4]
	JNE C4
	PUSH WORD PTR[BP+8]
	PUSH WORD PTR[BP+6]
	PUSH WORD PTR[BP-2]
	PUSH WORD PTR[BP-4]
	CALL CIRCLE_POINT
C4:	MOV SP,BP
	POP BP
	RET 6
CIRCLE ENDP

CIRCLE_POINT PROC NEAR
	PUSH BP
	MOV BP,SP
 	SUB SP,16
	MOV AX,WORD PTR[BP+10]	;
	ADD AX,WORD PTR[BP+6]	;
	MOV WORD PTR[BP-2],AX	;XC+X
	MOV AX,WORD PTR[BP+10]	;
	SUB AX,WORD PTR[BP+6]	;
	MOV WORD PTR[BP-4],AX	;XC-X
	MOV AX,WORD PTR[BP+10]	;			|	 |
	ADD AX,WORD PTR[BP+4]	;			|	 |
	MOV WORD PTR[BP-6],AX	;XC+Y			|	 |
	MOV AX,WORD PTR[BP+10]	;		   SP->	|	 |
	SUB AX,WORD PTR[BP+4]	;			|  YC-Y	 |<-BP-16 
	MOV WORD PTR[BP-8],AX	;XC-Y			|  YC+Y	 |<-BP-14
	MOV AX,WORD PTR[BP+8]	;			|  YC-X	 |<-BP-12
	ADD AX,WORD PTR[BP+6]	;			|  YC+X	 |<-BP-10
	MOV WORD PTR[BP-10],AX	;YC+X			|  XC-Y	 |<-BP-8
	MOV AX,WORD PTR[BP+8]	;			|  XC+Y	 |<-BP-6
	SUB AX,WORD PTR[BP+6]	;			|  XC-X	 |<-BP-4
	MOV WORD PTR[BP-12],AX	;YC-X			|  XC+X	 |<-BP-2
	MOV AX,WORD PTR[BP+8]	;			|   BP	 |<-BP
	ADD AX,WORD PTR[BP+4]	;			|返回地址|<-BP+2
	MOV WORD PTR[BP-14],AX	;YC+Y			|   Y	 |<-BP+4
	MOV AX,WORD PTR[BP+8]	;			|   X	 |<-BP+6
	SUB AX,WORD PTR[BP+4]	;			|   YC	 |<-BP+8	
	MOV WORD PTR[BP-16],AX	;YC-Y			|   XC 	 |<-BP+10   
	PUSH WORD PTR[BP-2]	;			|	 |
	PUSH WORD PTR[BP-14]	; 		     CIRCLE_POINT堆栈结构
	PUSH COLOR		 
	CALL PIXEL		 
	PUSH WORD PTR[BP-4]	 
	PUSH WORD PTR[BP-14]	 
	PUSH COLOR
	CALL PIXEL
	PUSH WORD PTR[BP-2]
	PUSH WORD PTR[BP-16]
	PUSH COLOR
	CALL PIXEL
	PUSH WORD PTR[BP-4]
	PUSH WORD PTR[BP-16]
	PUSH COLOR
	CALL PIXEL
	PUSH WORD PTR[BP-6]
	PUSH WORD PTR[BP-10]
	PUSH COLOR
	CALL PIXEL
	PUSH WORD PTR[BP-8]
	PUSH WORD PTR[BP-10]
	PUSH COLOR
	CALL PIXEL
	PUSH WORD PTR[BP-6]
	PUSH WORD PTR[BP-12]
	PUSH COLOR
	CALL PIXEL
	PUSH WORD PTR[BP-8]
	PUSH WORD PTR[BP-12]
	PUSH COLOR
	CALL PIXEL
 	MOV SP,BP
	POP BP
	RET 8
CIRCLE_POINT ENDP

;********************************
;清屏函数
;********************************
CLEAR PROC NEAR
	MOV BX,0
CLR1:   MOV ES:[BX],AL
	INC BX
	CMP BX,80*480
	JNB CLR2
	JMP CLR1
CLR2:	RET
CLEAR 	ENDP

;********************************
;设置写模式的函数
;********************************
SET_WRITE_MODE PROC NEAR
	PUSH AX
	MOV DX,3CEH
	MOV AL,5
	OUT DX,AL
	MOV DX,3CFH
	POP AX
	OUT DX,AL
	MOV DX,3CEH
	MOV AL,8
	OUT DX,AL
	MOV DX,3CFH
	MOV AL,0FFH
	OUT DX,AL
	RET
SET_WRITE_MODE ENDP
END START

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -