汇编语言系列之汇编实现简单数学运算

软件:emu8086

语言:汇编语言(Assembly)

注意:本文列出了两种算术运算的代码,全部代码为博主独自一人编写,会有瑕疵,谨慎使用。

5.计算S=1+2×3+3×4+4×5+···+N(N+1)

5.1设计要求:

设计程序,实现数学公式S=1+2×3+3×4+4×5+···+N(N+1)的算法。数值N由加键盘输入,计算结果在显示终端输出。设计要求:计算结果不超过十六位寄存器的存储能力,如有溢出提示错误。

5.2设计思路:

输入N值然后把N给BH作为循环次数,通过循环实现乘和累加计算,结果为十六进制,通过除以10得到十进制,存入堆栈再依次输出。

5.3程序清单:

DATA SEGMENT
 pkey DB 0dh,0ah,"pleas input N end by ';' :$"
 over DB 0AH,0DH,"overflow!",0dh,0ah,'$'
 result DB 0dh,0ah,'result is:','$'
 DAT1 DB 8 DUP(0)
DATA ENDS

STACK SEGMENT
 SSTACK DB 100 DUP(0)
STACK ENDS 

CODE SEGMENT
 ASSUME CS:CODE,DS:DATA,SS:STACK 
 
STATE: 
 MOV AX,DATA
 MOV DS,AX
 LEA SI,DAT1 ;开辟缓冲区
 LEA DX,pkey
 MOV AH,9
 INT 21H ;DOS功能调用,输出字符串
 
LLP:MOV AH,1
 INT 21H ;DOS功能调用,输入N值
 SUB AL,2FH 
 INC DX ;DX计数
 MOV [SI],AL ;将输入的数据存在SI缓冲区
 INC SI
 CMP AL,0CH ;输入为封号结束输入
 JNZ LLP
 SUB SI,2
 CMP DX,02H ;DX不为2表示输入为两位数
 JNZ LLLP 

LLP1:MOV CX,1
 MOV BL,2 ;赋初始值 
 JMP LP
LLLP:
 MOV DI,SI
 SUB DI,1 
 SUB [DI],1
 MOV AL,10
 MUL [DI]
 ADD [SI],AX ;输入是两位数时十位乘10加个位
 SUB AH,AH
 JMP LLP1
 
LP: MOV BH,[SI] ;把循环次数给BH
 MOV AL,BL
 INC BL
 MUL BL ;BL(加1)和AL(原值)相乘给AX
 ADD CX,AX ;AX和CX相加给CX,通过循环实现累加
 JO OOF ;如果溢出重新输入
 CMP BH,BL ;判断是否达到N值
 JNZ LP 
 MOV AX,CX
 MOV CX,0AH
 MOV BX,0 
 
 
LOP:MOV DX,0
 DIV CX ;AX表示的32位数除以10,商放在AX,余数放在DX
 INC BX
 ADD DX,30H
 PUSH DX ;将余数依次压入栈
 CMP AX,0
 JNZ LOP ;商不为0继续除10
 LEA DX,result
 MOV AH,9
 INT 21H ;DOS功能调用,输出字符串 
 
OUTPUT:
 POP DX
 MOV AH,2
 INT 21H ;DX中数据依次出栈并显示
 DEC BX
 JNZ OUTPUT ;出栈完成后停止
 JMP STATE 
 
OOF:LEA DX,over
 MOV AH,09H
 INT 21H ;DOS功能调用,溢出显示
 JMP STATE 
 
CODE ENDS

END STATE

5.4程序运行结果及分析:

乘法和累加计算根据流程图一步步赋值即可得到,在输入两位数和结果转十进制输出时遇到了麻烦,通过查找资料不断尝试,最终找到了简单的解决办法,即输入两位时移位累加,输出除以10存入堆栈并依次输出显示。

图5 计算S=1+2×3+3×4+4×5+···+N(N+1)设计结果

6.计算N!

6.1设计要求:

掌握汇编语言实现高级语言中数学函数的方法。设计程序,实现数学公式N!=N(N-1)(N-2)······2*1的算法。数值N由键盘输入,计算结果在显示终端输出。设计要求:N的范围为0-65535,即不超出16位寄存器的存储容量。

6.2设计思路:

输入N值,通过循环实现阶乘并将计算结果存入AX,然后十六进制转十进制输出。

6.3程序清单:

DATA SEGMENT 
 pkey DB 0AH,0DH,"Please Input N(1-8):",'$' 
 result DB 0AH,0DH,"the results is:",'$' 
 over DB 0AH,0DH,"overflow!",0AH,0DH,'$'
DATA ENDS 

STACK SEGMENT
 SSTACK DB 100 DUP(0)
STACK ENDS 

CODE SEGMENT
 ASSUME CS:CODE,DS:DATA,SS:STACK
 
STATE: 
 MOV AX,DATA
 MOV DS,AX ;数据段初始化

 LEA DX,pkey
 MOV AH,09H
 INT 21H ;DOS功能调用,显示字符串 
 
 MOV AH,1 
 INT 21H ;DOS功能调用,输入N 
 SUB AL,30H
 CMP AL,08H
 JA OOF ;输入大于8溢出 
 
 XOR AH,AH 
 MOV BP,AX ;赋循环计数值N给BP 
 
LP: MOV BX,BP
 DEC BX
 JZ LLP ;阶乘次数为BX,BX为0必须马上跳转
 MUL BX ;AX中存放阶乘结果(十六进制转十进制用)
 DEC BP
 JNZ LP 

LLP: MOV CX,0
 MOV BX,10
 
LLLP: MOV DX,0 
 DIV BX ;AX表示的32位数除以10,商放在AX,余数放在DX 
 ADD DX,30H 
 PUSH DX ;将余数转换为ASCII码值并压入栈
 INC CX
 CMP AX,0 ;商不为0就继续除10
 JNZ LLLP 

 MOV AH,09H
 LEA DX,result 
 INT 21H ;DOS功能调用,输出字符串
 
LOP: POP DX 
 MOV AH,2 
 INT 21H ;DX各位出栈并显示
 LOOP LOP 
 JMP STATE 

OOF: LEA DX,over
 MOV AH,09H
 INT 21H ;DOS功能调用,溢出显示
 JMP STATE 
 
CODE ENDS
 END STATE

6.4程序运行结果及分析:

阶乘部分是利用MUL指令AX中存放计算结果并实现阶乘,除阶乘计算部分外,其它部分和第五题类似,同样结果转十进制输出时遇到了麻烦,利用除以10存入堆栈再依次取出并显示来实现。

图6 计算N!设计结果

作者:BoBoRing原文地址:https://www.cnblogs.com/BoBoRing/p/10240865.html

%s 个评论

要回复文章请先登录注册