软件: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!设计结果
来源:oschina
链接:https://my.oschina.net/u/4417891/blog/3683883