【汇编】图形打印(.asm源码)

项目环境
  • 编译环境:搭建一个nasm2.8的编译环境。
  • 镜像文件:采用winhex_18.2刷入编码。
  • 虚拟机:采用Bochs-2.4.5
项目软件
运行结果
  • 简单得说就是你能得到一个二维矩阵点,你就能打印图形,图片等等形状。
    在这里插入图片描述
程序源码(.asm)
org 0x8400

;CS,DS,ES,SS默认的段基址为0000
;利用jmp指令跳过段数据的定义部分
jmp start

;其中0号默认为背景色,1号默认为画笔的颜色
pallete:
	db 0,255,255,255	;白色背景色
	db 1,0,0,0			;黑色
	db 2,255,0,0		;红色

;画笔色号
pen:
	db 1

;直线起始(x,y),长度len
linex:
	dw 0
liney:
	dw 0
linelength:
	dw 1


;字符起始位置(x,y)
charStartX:				;起始x位置
	dw 0
charStartY:				;起始y位置
	dw 0
tempX:					;临时存储变量x
	dw 0
tempY:					;临时存储变量y
	dw 0
charLength:				;汉字16宽
	dw 16
charHeight:				;汉字48高
	dw 64
charSum:				;在字符点阵中的偏移总量
	dw 0
charX:					;汉字矩阵二维数组的x
	dw 0
charY:					;汉字矩阵二维数组的y
	dw 0
charVertical:
	dw 0
charHorizontal:
	dw 0
character:				;汉字矩阵
	db 0,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,
	db 0,0,0,0,1,1,1,0,1,0,1,0,0,0,0,0,
	db 0,1,1,1,1,0,0,0,1,0,0,1,0,0,0,0,
	db 0,0,0,0,1,0,0,0,1,0,0,1,0,0,0,0,
	db 0,0,0,0,1,0,0,0,1,0,0,0,0,1,0,0,
	db 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,
	db 0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,
	db 0,0,0,0,1,0,0,0,1,0,0,1,0,0,0,0,
	db 0,0,0,0,1,0,1,0,1,0,0,1,0,0,0,0,
	db 0,0,0,0,1,1,0,0,0,1,1,0,0,0,0,0,
	db 0,0,0,1,1,0,0,0,0,1,0,0,0,0,0,0,
	db 0,1,1,0,1,0,0,0,1,0,1,0,0,0,0,0,
	db 0,0,0,0,1,0,0,1,0,0,1,0,0,0,0,0,
	db 0,0,0,0,1,0,1,0,0,0,0,1,0,1,0,0,
	db 0,0,1,0,1,0,0,0,0,0,0,1,0,1,0,0,
	db 0,0,0,1,0,0,0,0,0,0,0,0,1,1,0,0,

	db 0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,
	db 0,0,1,1,1,1,1,1,1,0,0,0,0,0,0,0,
	db 0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,0,
	db 0,0,0,0,1,0,0,1,0,0,1,0,0,0,0,0,
	db 0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,
	db 0,1,0,0,0,0,1,0,0,0,0,0,0,0,1,0,
	db 1,0,0,0,0,0,1,0,0,0,0,0,0,1,0,0,
	db 0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,
	db 0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,
	db 0,0,0,0,0,1,1,1,1,1,1,1,0,0,0,0,
	db 0,0,0,0,1,0,1,0,0,0,1,0,0,0,0,0,
	db 0,0,0,0,1,0,0,1,0,1,0,0,0,0,0,0,
	db 0,0,0,1,0,0,0,0,1,0,0,0,0,0,0,0,
	db 0,0,0,1,0,0,0,1,0,1,1,0,0,0,0,0,
	db 0,0,1,0,0,0,1,0,0,0,0,1,1,1,0,0,
	db 0,0,0,0,1,1,0,0,0,0,0,0,1,0,0,0,

	db 0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,
	db 0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,
	db 0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,
	db 0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,
	db 0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,
	db 0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,
	db 0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,
	db 0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,
	db 0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,
	db 0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,
	db 0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,
	db 0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,
	db 0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,
	db 0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,
	db 0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,
	db 0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,

	db 0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,
	db 0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,
	db 0,1,0,0,0,0,0,0,0,0,1,0,0,1,0,0,
	db 0,1,0,1,1,1,1,1,1,1,1,1,0,1,0,0,
	db 0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,
	db 0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,
	db 0,1,0,0,0,0,0,1,0,1,0,0,0,1,0,0,
	db 0,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,
	db 0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,
	db 0,1,0,0,0,0,0,1,0,1,0,0,0,1,0,0,
	db 0,1,0,0,0,0,0,1,0,0,1,0,0,1,0,0,
	db 0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,
	db 0,1,0,1,1,1,1,1,1,1,1,1,0,1,0,0,
	db 0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,
	db 0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,
	db 0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,

	
;主函数入口地址
start:
	;进入13320*200 256色的图形模式	
	mov ah,00h
	mov al,13h
	int 10h

	mov si,pallete
	call editcolor								;第一个颜色,背景色,白色
	call editcolor								;第二个颜色,黑色
	call editcolor								;第三个颜色,红色

	mov ax,0xa000								;0xb800为显存的段基址
	mov es,ax
	
	;初始化画笔和字符起始位置
	mov byte[ds:pen],1
	mov word[ds:charStartX],0
	mov word[ds:charStartY],0
	call paint_char
	x:	
		jmp $


;编制自定义颜色
editcolor:
	push dx										;压栈
	push ax										;压栈
	push si										;压栈

	mov dx,0x3c8								;设置颜色号接口0x3c8
	mov al,[si]
	out dx,al
	mov dx,0x3c9								;RGB分量接口0x3c9
	mov al,[si+1]
	out dx,al
	mov al,[si+2]
	out dx,al
	mov al,[si+3]
	out dx,al
	add si,4

	pop si										;出栈
	pop ax										;出栈
	pop dx										;出栈

	ret

;绘制一条竖线
paint_vertical_line:
	push cx										;压栈
	push ax										;压栈
	push bx										;压栈
	push si										;压栈

	mov cx,[ds:linex]							;cx,起始横坐标
	mov ax,[ds:liney]							;ax,起始纵坐标
	mov bx,[ds:linelength]						;bx,直线长度

	;用乘法计算横纵坐标
	mov si,320
	mul si
	add ax,cx
	
	mov dx,bx									;直线总长度
	mov si,ax									;绘图起始位置
	mov bx,0									;变化偏移量
	mov ax,0									;变化次数
	
	mov cl,[ds:pen]								;cl,画笔色号

	loop_paint_vertical_line:
		cmp ax,dx
		jae exitpaintvl
		mov byte [es:bx+si], cl
		add bx,320
		inc ax
		jmp loop_paint_vertical_line

	exitpaintvl:
		pop si									;出栈
		pop bx									;出栈
		pop ax									;出栈
		pop cx									;出栈
		ret



;字符打印
paint_char:										;循环初始化
	push ax										;压栈
	push dx										;压栈
	push bx										;压栈
	push cx										;压栈

	mov word[ds:charSum],0						;防止另外程序写入,重新置偏移总量为0
	mov word[ds:charVertical],0					;防止另外程序写入,重新置竖直偏移量为0
	mov word[ds:charHorizontal],0				;防止另外程序写入,重新置水平偏移量为0

	;起始x
	mov ax,[ds:charStartX]						
	mov word[ds:charX],ax
	;起始y
	mov ax,[ds:charStartY]
	mov word[ds:charY],ax
	
	paint_char_column_loop:						;列循环
		mov dx,[ds:charHeight]					;字高度
		cmp word[ds:charVertical],dx			;与字竖直偏移量比较
		jae exit_char_paint						;若竖直偏移量大于等于字高度,退出

		;行循环	
		mov word[ds:charHorizontal],0			;行循环初始化
			
		paint_char_row_loop:					;行循环
			;比较判断是否跳出行循环,进入列循环
			mov bx,word[ds:charHorizontal]		;字水平偏移量
			cmp bx,[ds:charLength]				;与字长度比较
			jae next_column_loop				;若字水平偏移量大于等于字长度,退出

			mov bx,[ds:charSum]
			cmp byte[character+bx],1
			jne next_row_loop
			
			mov cx,[ds:charX]
			mov word[ds:linex],cx

			mov cx,[ds:charY]
			mov word[ds:liney],cx
			
			mov word[ds:linelength],1

			call paint_vertical_line
		;行循环处理下一次
		next_row_loop:
			inc word[ds:charX]
			inc word[ds:charHorizontal]
			inc word[ds:charSum]

			jmp paint_char_row_loop

	next_column_loop:
		;列层循环的下一次
		inc word[ds:charVertical]				;竖直偏移量++
		mov word[ds:charHorizontal],0			;水平偏移量置0
		;重置字符(x,y)
		mov ax,[ds:charStartX]
		mov word[ds:charX],ax
		mov ax,[ds:charVertical]
		add ax,[ds:charStartY]
		mov word[ds:charY],ax

		jmp paint_char_column_loop
		
	exit_char_paint:
		push ax									;出栈
		push dx									;出栈
		push bx									;出栈
		push cx									;出栈
		ret
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

敲代码两年半的练习生

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值