windows下使用masm汇编器的斐波那契数列彩色输出实验

    写作原因:操作系统课程实验8086汇编的ddl驱动。虽然只是入门,但是由于个人不是特别喜欢过于晦涩难懂的jmp之类的跳转,所以使用较多的较高级的指令和伪指令

    源码缺陷:没有实现超过24项(16位存储单元限制),在彩色输出的时候没有考虑换行

    有关指令的含义请自行百度、谷歌、或百谷歌度。

    源码说明:

     fib.asm中包含生成斐波那契数列的子程序接口fib

     int.asm中包含将int和int数组转成string的子程序接口intToString和intListToString

     output.asm中包含将字符串彩色输出的子程序接口colorfulPrint

     main.asm主程序入口

     head.inc头文件

     文件中包含一些对接口小测试,可以忽略

    

    fib.asm

include head.inc

public fib

stackseg	segment'stack'
	db	100
stackseg	ends


dataseg	segment'data'
	numSpace:	db	50	dup(0)
	numStrSpace:	db	250	dup('$')
	str:	db	20	dup('$')	
dataseg	ends	

codeseg	segment'code'

fib	proc far C 	uses ax bx cx dx di, destOffset:word, num:word
	mov	di, destOffset
	
	mov	ax, 1
	mov	dx, 1
	mov	cx, num
	.while  cx > 0
		stosw
		mov	bx, dx
		add	dx, ax
		mov	ax, bx
		dec	cx
	.endw
	ret
fib	endp

start:
	mov	ax, dataseg
	mov	ds, ax
	mov	es, ax
	mov	ax, stackseg
	mov	ss, ax

	mov	ax, 12;我真是了了个去了,都push pop ax了invoke以后还会变
	lea	bx, numSpace
	invoke	fib, numSpace, ax
	mov	ax, 12
	mov	bx, numStrSpace
	invoke	intListToString, numSpace, ax, bx
	invoke	colorfulPrint, bx, dx
	mov	ah, 4ch
	int	21h
codeseg	ends
end	start

     

    int.asm

public intListToString, intToString

dataseg		segment'data'
	integer:	dw 0001h,0001h,0002h,0003h,0005h,0008h,000dh
	str:	db	30 dup(0),'$'
dataseg	ends

stackseg	segment'stack'
	db	200	dup(00h)
stackseg	ends
	
codeseg	segment'code'


intToString	proc far C	uses ax bx cx, theInt:word, strOffset:word
	mov	ax, [theInt]
	mov	dx, 0
	mov	cx, 0
	mov	bx, 000Ah
	
	.repeat
		div	bx
		add	dx, '0'
		push	dx
		mov	dx, 0
		inc	cx;计算数位个数
	.until ax == 0
	;存到目的地址
	mov	bx, strOffset
	mov	dx, cx
	.repeat
		pop	ax
		mov	[bx], al
		inc	bx
	.untilcxz
	ret
intToString	endp


intListToString	proc far C 	uses ax cx si di, intListOffset:word, intNum:word, strListOffset:word
	mov	si, intListOffset
	mov	di, strListOffset

	mov	cx, intNum
	.repeat
		lodsw
		invoke intToString, ax, di
		add	di, dx
		mov	al, ' '
		stosb
	.untilcxz
	mov	al, '$'
	stosb
	sub	di, strListOffset
	sub	di, 2
	mov	dx, di
	ret
intListToString	endp

start:
	mov	ax, dataseg
	mov	ds, ax
	mov	es, ax
	mov	ax, stackseg
	mov	ss, ax
	
	mov	sp, 200
	lea	bx, integer
	lea	dx, str
	invoke	intListToString, bx, 7, dx
	mov	ah, 09h
	int	21h
	mov	ah, 4ch
	int	21h
codeseg	ends
end	start


    output.asm

include	head.inc

public colorfulPrint

yellow	equ	0eh
blue	equ	01h

dataseg	segment'data'
	str:	db	"hello!assembly!",'$'
	strLen	equ	($-1-str)h
dataseg	ends

stackseg	segment'stack'
	db	50
stackseg	ends

codeseg	segment'code'

colorfulPrint	proc far C	uses ax bx cx dx, srcOffset:word, len:word
	mov	cx, len
	mov	si, srcOffset 
	.repeat
		lodsb
		push	ax
	.untilcxz
	
	mov	dx, 0
	mov	cx, len
	mov	bl, yellow
	.repeat
		pop	ax
		mov	ah, 09h
		int	10h
		inc	dl
		;转变颜色
		.if bl == 0fh
			mov	bl, 01h
		.else
			inc	bl
		.endif
	.untilcxz
	ret	
colorfulPrint	endp

start:
	mov	ax, dataseg
	mov	ds, ax
	mov	es, ax
	mov	ax, stackseg
	mov	ss, ax	
	
	lea	bx, str
	mov	ax, 15
	invoke	colorfulPrint, bx, ax

	mov	ah, 4ch
	int	21h
codeseg	ends
end	start


    main.asm

include head.inc

stackseg segment'stack'
	db 200
stackseg ends

dataseg	segment 'data'
	requestMessage:	db	"Please enter the terms in Fibonacci numbers:",'$'
	;不同版本下字符串结束标识符是不一样的,masm的windows版本和linux版本都是'$',nasm的windows版本是0,linux版本是10,dos版本是'$',at&t汇编标准没有查过。	requestMessageLen	equ	($-requestMessage-1)
	num:	db	2 dup('$'),'$'
	numSpace:	db	32 dup(0)
	numStrSpace:	db	80 dup('$')	
dataseg ends

codeseg	segment 'code'

;接受并解析输入的数字,并放到dx中
inputNum	proc C	uses ax bx cx
	;显示欢迎信息
	lea	dx, requestMessage
	mov	ah, 09h
	int	21h
	;接受输入
	mov	dx, num
	mov	ah, 0ah
	int	21h
	
	;解析输入
	mov	cx, 0
	lea	bx, num+2
	mov	ah, 0
	mov	al, [bx]
	inc	bx
	.if	al>='0' && al<='9'
		sub	al, '0'
		mov	dl, [bx]
		.if	dl>='0' && dl<='9';十位数,写成[bx]!='$'是没有用的
			mov	dx, 10
			mul	dx
			add	cx, ax
			mov	al, [bx]
			sub	al, '0'
			add	cx, ax
		.else;个位数
			add	cx, ax
		.endif
	.endif

	.if	cx > 24
		mov	dx, 24
	.else
		mov	dx, cx
	.endif
	ret
inputNum	endp

clrf	proc far C	uses ax dx
	mov	dl, 0dh
	mov	ah, 02h
	int	21h
	mov	dl, 0ah
	mov	ah, 02h
	int	21h
	ret
clrf	endp

start:	
	mov	ax, dataseg
	mov	ds, ax
	mov	es, ax
	mov	ax, stackseg
	mov	ss, ax	

	invoke	inputNum
	invoke	clrf
	lea	bx, numSpace
	invoke	fib, numSpace, dx
	mov	bx, numStrSpace
	invoke	intListToString, numSpace, dx, bx
	invoke	colorfulPrint, bx, dx
	mov	ah, 4ch
	int	21h
codeseg	ends
end start


    head.inc

colorfulPrint	proto far C	srcOffset:word, len:word

intToString	proto far C	theInt:word, strOffset:word

intListToString	proto far C 	intListOffset:word, intNum:word, strListOffset:word

fib	proto far C 	destOffset:word, num:word

clrf	proto	far	C


    编译:masm    main

            ...

    连接:  link main + fib + output + int

    运行: main

    初学者,对其中的一些指令的理解和对性能的追求并不是很到位,可相互借鉴

转载于:https://my.oschina.net/designing/blog/403230

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值