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

📄 caculatorv20.asm

📁 用x86汇编语言编写的计算器
💻 ASM
字号:
;算术表达式计算,16位定点,溢出,除0报告,要求运算错误能恢复,
;尽量压缩文件大小,紧奏。
;CaculatorV2.0


.8086
;*******************************************************************************
;*******************************************************************************

prognam		segment 
	assume cs:prognam, ds:prognam, ss:prognam,
	
;*******************************************************************************

main	proc	near					;enter proc
	;-----------------------------------------------------------------------
			mov	ax, prognam			;initial ritual
			mov	ds, ax
	;-----------------------------------------------------------------------
			mov	oldsp, sp			;save sp and show welcome
			call	nextline
			mov	dx, offset welcome_str
			call	showbuffer
			jmp	short initial
	;-----------------------------------------------------------------------
	continuteornot: 					;test whethe to continute
			mov	dx, offset continute_str
			call	showbuffer
			mov	ah, 1h
			int	21h
			cmp	al, 'y'
			jz	short initial
			cmp	al, 'Y'
			jz	short initial
			cmp	al, 0dh
			jz	short initial
			cmp	al, 'n'
			jz	near ptr main_end
			cmp	al, 'N'
			jz	near ptr main_end
			call	nextline
			jmp	short continuteornot
	;-----------------------------------------------------------------------
	initial:	call	nextline
			call	nextline
			mov	dx, offset initial_str		;show initial information
			call	showbuffer
			mov	ah, 0ah				;get in char buffer
			mov	dx, offset char_lenght
			int 	21h
	;-----------------------------------------------------------------------		
			sub	cx, cx				;add "="
			mov	cl, actlen
			jcxz	short continuteornot
			call	nextline
			mov	bx, offset char_buffer
			add	bx, cx
			mov	[bx], '='
			inc	actlen
	;-----------------------------------------------------------------------
			call	caculation			;real caculation
	;-----------------------------------------------------------------------
			mov	dx, offset result_str
			call	showbuffer
			mov	ax, opnd			;show result	
			mov	bx, offset char_buffer
			add	bx, 10h
			mov	byte ptr [bx], '$'
			;-------------------------------------------------------
			sub	si, si
			cmp	ax, 0h				;if result is below 0
			jz	short printzero
			jg	short abovezero
			neg	ax
			mov	si, 1h
			;-------------------------------------------------------
	abovezero:	mov	cx, 10				;if result is above 0
	loopdigit:	sub	dx, dx
			div	cx
			add	dl, '0'
			dec	bx
			mov	byte ptr [bx], dl
			cmp	ax, 0
			jnz	short loopdigit
			cmp	si, 0
			jz	short showend
			dec	bx
			mov	byte ptr [bx], '-'
			jmp	short showend
			;-------------------------------------------------------
	printzero:	dec	bx				;if result equ 0
			mov	byte ptr [bx], '0'
			;-------------------------------------------------------
	showend:	mov	dx, bx
			call	showbuffer
			call	nextline			;turn to next line
			jmp	near ptr continuteornot
	;-----------------------------------------------------------------------
	main_error:	mov	dx, offset error_str		;due with error
			jmp	short showerror
	overflow:	mov	dx, offset overflow_str
			jmp	short showerror
	divisorzero:	mov	dx, offset divisor_str
	showerror:	call	showbuffer
			mov	sp, oldsp
			jmp	near ptr continuteornot
	;-----------------------------------------------------------------------
	main_end:	call	nextline
			mov	ax, 4c00h
			int	21h
	;-----------------------------------------------------------------------
main	endp

;*******************************************************************************

showbuffer	proc	near			;show a line of char
	mov	ah, 9h				;using ah adn dx
	int	21h
	ret
showbuffer	endp

;*******************************************************************************

nextline	proc	near			;show a line of char
	mov	ah, 9h				;using ah adn dx
	mov	dx, offset nextline_str
	int	21h
	ret
nextline	endp

;*******************************************************************************

caculation	proc	near
	;-----------------------------------------------------------------------
			mov	opnd_top, offset opnd		;initial for caculation
			mov	optr_top, offset optr
			inc	optr_top
			mov	optr, 6
			mov	char_top, offset char_buffer
			mov	char_end, offset actlen
			mov	al, actlen
			sub	ah, ah
			add	char_end, ax
			mov	al, char_buffer
			mov	currentchar, al
			mov	caculat_cnt, 100h
	;-----------------------------------------------------------------------
	nextopr:	dec	caculat_cnt			;has it reach the end?
			jz	near ptr main_error
			cmp	opnd_top, offset opndtest
			jnz	short notendyet
			mov	ax, char_end
			cmp	char_top, ax
			jz	near ptr caculat_end
		;-------------------------------------------------------
	notendyet:	cmp	currentchar, ' '		;skip blank
			jnz	short notblank
			inc	char_top
			mov	bx, char_top
			mov	al, [bx]
			mov	currentchar, al
			jmp	short nextopr	
		;-------------------------------------------------------
	notblank:	cmp	currentchar, '0'		;is it opratand?
			jl	short notopnd
			cmp	currentchar, '9'
			jg	short notopnd
		;-------------------------------------------------------
			sub	ax, ax				;char to volume
			mov	bx, char_top
	nextdigit:	mov	cl, [bx]
			cmp	cl, '0'
			jl	short pushopnd
			cmp	cl, '9'
			jg	short pushopnd
			mov	dx, 10
			mul	dx
			jo	near ptr overflow
			mov	dh, 10000000b
			and	dh, ah
			jnz	near ptr overflow
			sub	cl, '0'
			add	al, cl
			adc	ah, 0h
			jo	near ptr overflow
			inc	bx
			jmp	short nextdigit
		;-------------------------------------------------------
	pushopnd:	mov	char_top, bx			;push the opnd
			mov	currentchar, cl
			mov	bx, opnd_top
			mov	[bx], ax
			add	opnd_top, 2h
			jmp	near ptr nextopr
	;-----------------------------------------------------------------------
	notopnd:	mov	al, currentchar			;test whethe ( and )
			cmp	al, ')'
			jnz	otheropnd
			mov	bx, optr_top
			mov	dl, [bx-1]
			cmp	dl, 04h
			jnz	otheropnd
			dec	optr_top
			inc	char_top
			mov	bx, char_top
			mov	dl, byte ptr [bx]
			mov	currentchar, dl
			jmp	near ptr nextopr
		;-------------------------------------------------------
	otheropnd:	cmp	al, '+'				;test what optr is it
			jz	charadd
			cmp	al, '-'
			jz	charsub
			cmp	al, '*'
			jz	charmul
			cmp	al, '/'
			jz	chardiv
			cmp	al, '('
			jz	charleft
			cmp	al, ')'
			jz	charright
			cmp	al, '='
			jz	charequ
			jmp	near ptr main_error
		;-------------------------------------------------------
	charadd:	mov	ch, 10000000b			;get ready for precedence test
			sub	ah, ah
			jmp	short testpreced
	charsub:	mov	ch, 01000000b
			mov	ah, 1h
			jmp	short testpreced
	charmul:	mov	ch, 00100000b
			mov	ah, 2h
			jmp	short testpreced
	chardiv:	mov	ch, 00010000b
			mov	ah, 3h
			jmp	short testpreced	
	charleft:	mov	ch, 00001000b
			mov	ah, 4h
			jmp	short testpreced	
	charright:	mov	ch, 00000100b
			mov	ah, 5h
			jmp	short testpreced
	charequ:	mov	ch, 00000010b
		;-------------------------------------------------------
	testpreced:	mov	bx, optr_top			;test the precedence of optr
			sub	dx, dx
			mov	dl, [bx-1]
			xchg	dx, bx
			mov	cl, pritable[bx]
			xchg	dx, bx
			and	cl, ch
			jnz	to_caculat			;if former optr in pri
		;-------------------------------------------------------
			mov	[bx], ah			;later optr in pri
			inc	optr_top
			inc	char_top
			mov	bx, char_top
			mov	dl, byte ptr [bx]
			mov	currentchar, dl
			jmp	nextopr
	;-----------------------------------------------------------------------
	to_caculat:	dec	optr_top			;real caculat, get ready
			sub	opnd_top, 2h
			mov	cl, dl
			mov	bx, opnd_top
			mov	dx, [bx]
			mov	ax, [bx-2]
		;-------------------------------------------------------
			cmp	cl, 0				;test what kind of optr
			jz	short toadd
			cmp	cl, 1
			jz	short tosub
			cmp	cl, 2
			jz	short tomul
			cmp	cl, 3
			jz	short todiv
			jmp	near ptr main_error
		;-------------------------------------------------------
	toadd:		add	ax, dx
			jmp	short newopnd
	tosub:		sub	ax, dx
			jmp	short newopnd
	tomul:		imul	dx
			jmp	short newopnd
	todiv:		cmp	dx, 0h
			jz	near ptr divisorzero
			mov	cx, dx
			cwd
			idiv	cx
			clc
		;-------------------------------------------------------
	newopnd:	jo	near ptr overflow
			mov	[bx-2], ax
			jmp	near ptr nextopr
	;-----------------------------------------------------------------------
	caculat_end:	
			ret
caculation	endp

;*******************************************************************************
	;-----------------------------------------------------------------------
	char_lenght	db	50		;data buffer
	actlen		db	?
	char_buffer	db	51 dup(?)
	opnd		dw	?
	opndtest	dw	10 dup(?)
	optr		db	10 dup(?)
	;-----------------------------------------------------------------------
	currentchar	db	?
	opnd_top	dw	?
	optr_top	dw	?
	char_top	dw	?
	char_end	dw	?
	caculat_cnt	dw	?
	oldsp		dw	?
	;-----------------------------------------------------------------------
	pritable	db	11000110b	;precedence information
			db	11000110b
			db	11110110b
			db	11110110b
			db	00000010b
			db	11111110b
			db	00000010b
	;-----------------------------------------------------------------------
	welcome_str	db	0dh, 0ah, 0dh, 0ah,"Caculator2.0", 0dh, 0ah
			db	"Public by SilentEcho, all right reserved",'$'
	result_str	db	"RESULT:  ", '$'
	overflow_str	db	"ERROR: Overflow, only 16 Bit available", 0dh, 0ah, '$'
	initial_str	db	"Please enter an expression", 0dh, 0ah, '$'
	error_str	db	"ERROR: Invalid expression", 0dh, 0ah, '$'
	divisor_str	db	"ERROR: Divisor is Zero", 0dh, 0ah, '$'
	continute_str	db	"Would you want to continute? [Yes/No] [Y]", '$'
	nextline_str	db	0dh, 0ah, '$'
			db	10 dup(?)
	result		db	0dh, 0ah, '$'
	;-----------------------------------------------------------------------
;*******************************************************************************

prognam		ends

;*******************************************************************************
;*******************************************************************************

	end	main
	
	
	
	
	
	
	
	
	
	
	
	
	;-----------------------------------------------------------------------
		
		;-------------------------------------------------------
	
		;-------------------------------------------------------
	
		;-------------------------------------------------------

	;-----------------------------------------------------------------------

		;-------------------------------------------------------
	
		;-------------------------------------------------------
	
		;-------------------------------------------------------
		
	;-----------------------------------------------------------------------

		;-------------------------------------------------------
	
		;-------------------------------------------------------
	
		;-------------------------------------------------------
		
	;-----------------------------------------------------------------------

		;-------------------------------------------------------
	
		;-------------------------------------------------------
	
		;-------------------------------------------------------

	;-----------------------------------------------------------------------

		;-------------------------------------------------------
	
		;-------------------------------------------------------
	
		;-------------------------------------------------------

	;-----------------------------------------------------------------------	
	

⌨️ 快捷键说明

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