32位汇编写简单加减乘除计算器

使用Visual Studio 2015开发,引用到Intel汇编的Irvine32头文件,头文件下载地址:http://kipirvine.com/asm/gettingStartedVS2015/Irvine.zip

具体的Visual Studio 2015配置汇编环境方法,自行解决。

https://www.youtube.com/watch?v=9e1ER2o83N0

这个视频提供VS2015的配置方法。

16-bit applications will run under the 32-bit versions of Windows (XP, Vista, 7). But 16-bit applications will not run directly in any 64-bit version of Windows.

16位汇编现在只能在32位的Windows xp,Vista , 7以及更早的系统上运行,现在的64位机器无法直接运行16位汇编程序!

具体汇编代码如下:

TITLE MyProject make by LSX (LSXproject.asm)
;***********************************************************
; 版权所有 (C)2017, LSX
;
; 文件名称: LSXproject.asm
; 内容摘要:该代码用于实现简单的计算器任务,并且将结果以16进制的形式输入到文件,负数以补码形式保存
; 当前版本: V1.0
; 作   者:LSX
; 完成日期: 20170707
;**********************************************************

INCLUDE Irvine32.inc	;包含的Intel汇编的头文件

.data
useroption		DWORD	?			; 用户输入的选择数字
firstNumber		DWORD	?			; 整型数字,有用户输入,?表示为某些数据预留的存储器单元
secondNumber	DWORD	?			; 用户输入的第二个数字
result			DWORD	?			; 运算结果


;file set
filename		BYTE	"result.txt",0	; 保存结果的文件
filehandle		DWORD	?				;文件句柄
fileerrormsg	BYTE	"File error!" , 0
;sizeof伪指令 = result大小 * result长度 , 多开辟两个空间备用
filestring		BYTE	sizeof result DUP(0) , 0 , 0 

;display menu
lineMenu	BYTE	"This is a simple calculator,input number to chose function",0dh,0ah
			BYTE	"			1.add function",0dh,0ah
			BYTE	"			2.sub function",0dh,0ah
			BYTE	"			3.mul function",0dh,0ah
			BYTE	"			4.div function",0


;basic strings
welcome		BYTE	"Welcome to my Assembly Language Project made by LSX.", 0	;打印消息
chosefunc	BYTE	"Please input your function number:",0
string1		BYTE	"Please input the first number:",0
string2		BYTE	"Please input the second number:",0
farewellmsg	BYTE	"Thank you use my program",0
diverrormsg	BYTE	"Your second number is zero!",0
inputerrormsg	BYTE	"Your input is illeagle!",0


;operate message
addResultMsg		BYTE	"Your result:" , 0

;Message Box Set
caption		BYTE	 "Message Box Test",0
question	BYTE	"Do you want to continue?",0


;改变字体颜色调用
colorset1 DWORD 11
colorset2 DWORD 16


.stack 100	;定义栈段

savereg MACRO	;保存现场宏指令
	push eax
	push ebx
	push ecx
	push edx
	push esi
	push edi
ENDM

returnreg MACRO	;恢复现场宏指令
	pop edi
	pop esi
	pop edx
	pop ecx
	pop ebx
	pop eax
ENDM

.code
main PROC
	push	colorset1
	push	colorset2
	call	changeColor

	;WriteString函数需要edx为字符串的入口地址为参数,并且字符串最后以0结尾
	mov		edx, OFFSET welcome	
	call	WriteString	;输出到控制台
	call	CrLf		;换行,由Irvine.inc提供

fileOperate:
;Create File
	;savereg

	mov		edx , OFFSET filename
	call	CreateOutputFile
	cmp		eax , INVALID_HANDLE_VALUE
	je		file_error
	mov		filehandle,eax
	;returnreg
	jmp		displaymenustart

file_error:
	mov		edx , OFFSET fileerrormsg
	call	WriteString
	call	CrLf
	jmp		stop_run

displaymenustart:
	call	displayMenu

chosefunction:
	mov		edx , OFFSET chosefunc
	call	WriteString
	call	ReadInt
	cmp		eax , 1
	jb		inputerror
	cmp		eax , 4
	jg		inputerror
	jmp		inputnumber


inputerror:
	mov		edx , OFFSET inputerrormsg
	call	WriteString
	call	CrLf
	jmp		chosefunction
	
inputnumber:
	mov		useroption , eax
	mov		edx , OFFSET string1
	call	WriteString
	call	ReadInt		;Irvine提供,返回值放在eax中
	mov		firstNumber, eax
	mov		edx , OFFSET string2
	call	WriteString
	call	ReadInt		;Irvine提供,返回值放在eax中
	mov		secondNumber, eax
	mov		eax , useroption
	cmp		eax , 1
	je		addFunction
	cmp		eax , 2
	je		subFunction
	cmp		eax , 3
	je		mulFunction
	cmp		eax , 4
	je		divFunction

addFunction:
	mov		eax , firstNumber
	add		eax , secondNumber
	jmp		displayResult

subFunction:
	mov		eax , firstNumber
	sub		eax , secondNumber
	jmp		displayResult

mulFunction:
	mov		eax , secondNumber
	imul	firstNumber		;mul指令,EAX 做乘数, 结果放在 EDX:EAX,但是简单起见,假设结果eax可以存放
	jmp		displayResult

divFunction:
	mov		eax , secondNumber
	cmp		eax , 0
	je		divError	
	mov		edx , 0
	mov		eax , firstNumber
	idiv	secondNumber	;将把 EDX:EAX 做被除数; 商 -> EAX, 余数 -> EDX
	jmp		displayResult

divError:
	mov		edx , OFFSET diverrormsg
	call	WriteString
	call	CrLf
	jmp		displaymenustart

displayResult:
	mov		result , eax
	mov		edx	, OFFSET addResultMsg
	call	WriteString
	call	WriteInt
	call	CrLf


;调用写入文件函数,此函数调用不需要指定任何参数
	pushf
	call    write_to_file
	popf

;调用对话框,ebx放对话框的标题,edx存放对话框内容
	mov		ebx, OFFSET caption
	mov		edx, OFFSET question
	call	MsgBoxAsk		; Yes eax=6 , No eax = 7
	cmp		eax , 7
	je		close_file
	jmp		chosefunction

close_file:
	mov		eax , filehandle
	call	CloseFile

stop_run:
	mov		edx, OFFSET farewellmsg	;调用结束语
	call	WriteString
	call	CrLf
	call	WaitMsg
	exit
main ENDP


;*****************************************************************
; 子程序:changeColor
; 功能:改变控制台颜色
; 入口参数:colorset1和colorset2在调用函数之前压入栈中
; 出口参数:无
; 调用注意事项:colorset1和colorset2必须是0-16的整形数字
;*****************************************************************

changeColor PROC

	; 天蓝色为控制台的字体颜色,若要改变颜色请自行设置colorset值
	push	ebp				;使用到ebp,需要压栈,32位4个字
	mov		ebp, esp

	mov		eax, [ebp + 8]  ; colorset1
	imul	eax, 16
	add		eax, [ebp + 12] ; colorset2
	call	setTextColor

	pop		ebp
	ret		8								; 清除栈,等价于将两个colorset去除,俩pop指令

changeColor	ENDP

;*****************************************************************
; 子程序:displayMenu
; 功能:	展示菜单
; 入口参数:无
; 出口参数:无
; 调用注意事项:无
;*****************************************************************

displayMenu	PROC
	;使用时先进行压栈操作,最后进行出栈操作
	savereg

	mov		edx, OFFSET lineMenu
	call	WriteString	;输出到控制台
	call	CrLf		;换行,由Irvine.inc提供

	returnreg
	ret

displayMenu ENDP

;*****************************************************************
; 子程序:write_to_file
; 功能:	将运算结果保存至文件
; 入口参数:无
; 出口参数:无
; 调用注意事项:规范起见在调用函数之外进行标志寄存器压栈
;*****************************************************************

write_to_file PROC
;使用时先进行压栈操作,最后进行出栈操作
	savereg

	mov		edx , OFFSET filestring	;将生成的数字移入filestring处
	
;从这里开始每个地方进行相似的操作,因为数字由高位到地位排放,所以右移的时候开始是28位,每次减少4位,并且
;一次只要4位。
	mov		eax , result
	shr		eax , 28
	add		al , 30h	;数字转化位ASCII码
	cmp		al , 58		;Ascii码‘9’对应57,所以从58开始比较
	jl		L1
	add		al , 7
L1:
	mov		byte ptr [edx], al
	inc		edx 

	mov		eax , result
	shr		eax , 24
	and		ax , 1111b
	add		al , 30h
	cmp		al , 58
	jb		L2
	add		al , 7
L2:
	mov		byte ptr [edx], al
	inc		edx 

	mov		eax , result
	shr		eax , 20
	and		ax , 1111b
	add		al , 30h
	cmp		al , 58
	jl		L3
	add		al , 7
L3:
	mov		byte ptr [edx], al
	inc		edx 

	mov		eax , result
	shr		eax , 16
	and		ax , 1111b
	add		al , 30h
	cmp		al , 58
	jl		L4
	add		al , 7
L4:
	mov		byte ptr [edx], al
	inc		edx 

	mov		eax , result
	shr		eax , 12
	and		ax , 1111b
	add		al , 30h
	cmp		al , 58
	jl		L5
	add		al , 7
L5:
	mov		byte ptr [edx], al
	inc		edx 

	mov		eax , result
	shr		eax , 8
	and		ax , 1111b
	add		al , 30h
	cmp		al , 58
	jl		L6
	add		al , 7
L6:
	mov		byte ptr [edx], al
	inc		edx 

	mov		eax , result
	shr		eax , 4
	and		ax , 1111b
	add		al , 30h
	cmp		al , 58
	jl		L7
	add		al , 7
L7:
	mov		byte ptr [edx], al
	inc		edx 

	mov		eax , result
	and		ax , 1111b
	add		al , 30h
	cmp		al , 58
	jl		L8
	add		al , 7
L8:
	mov		byte ptr [edx], al
	inc		edx 

	mov		byte ptr [edx] , 0dh	;写换行符,Windows是0dH,0aH。
	inc		edx
	mov		byte ptr [edx] , 0ah
	
;调用写入文件接口,eax是文件句柄,edx是要写入文件的起始地址
	mov		eax , filehandle
	mov		edx , OFFSET filestring
	mov		ecx , (TYPE result)*2 + 2	;存放的结果大小加2是要写入文件的大小
	call	WriteToFile

	returnreg
	ret

write_to_file ENDP

exit
end main



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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值