汇编计算数的阶乘,可计算1000万内的数的阶乘

合集下载

汇编计算数的阶乘,可计算1000万内的数的阶乘

汇编计算数的阶乘,可计算1000万内的数的阶乘

本程序作者cabbage功能:计算1亿以内数的阶乘E-mail:1225673051@;**********************求阶乘程序,十进制输入一个数,十进制输出其结果*********************STROUT MACRO ;宏,DOS功能调用,设置字符串输出入口参数MOV AH,09HINT 21HENDMCHAR_IN MACRO ;宏,DOS功能调用,设置字符输入入口参数MOV AH,01HINT 21HENDMDATAS SEGMENT PUBLICDATA1 DB 10H DUP(0)LEN1 DW ?LEN2 DW ?CONST1 DW 30CONST2 DW 40INDEX DB 10H DUP(0)STR0 DB '********************FACTORIAL**********************$'STR1 DB 0AH,0DH,'Please input the num:$'STR2 DB 0AH,0DH,'Error!$'STR3 DB 0AH,0DH,'The result is:$'STR4 DB 0AH,0DH,'****************************************************$'STR5 DB 0AH,0DH,'Thank you for using!$'DATA3 DB 0FF24H DUP(0)DATAS ENDSDATAS1 SEGMENT PUBLICDB 0FFFFH DUP(0)DATAS1 ENDSDATAS2 SEGMENT PUBLICDATA2 DB 0FFFFH DUP(0)DATAS2 ENDSDATAS3 SEGMENT PUBLICDB 0FFFFH DUP(0)DATAS3 ENDSSTACKS SEGMENT STACKDW 2000H DUP(?)TOP LABEL WORDSTACKS ENDSCODES1 SEGMENTASSUME CS:CODES1,DS:DATAS,SS:STACKS,ES:DATAS2START:MOV AX,DATASMOV DS,AXMOV AX,STACKSMOV SS,AXMOV AX,DATAS2MOV ES,AXMOV SP,OFFSET TOPMOV LEN1,OFFSET DATA2MOV LEN2,OFFSET DATA3MOV DX,OFFSET STR0STROUTs1:CALL ZERO ;清零DATA1,DATA2,DATA3,INDEX,为保证运行结果不受前次影响XOR AX,AXXOR BX,BXXOR CX,CXXOR DX,DX ;清零AX,BX,CX,DX等寄存器,为保证运行结果不受前次影响MOV DX,OFFSET STR1STROUTXOR SI,SIdo1:CHAR_INCMP AL,0DHJZ d1CMP AL,'0'JB errorCMP AL,'9'JA errorSUB AL,'0'MOV DS:BYTE PTR [SI],AL ;输入原始数据,按位输入,高位先输INC SIJMP do1d1:CMP SI,0JZ exitMOV CX,SIXOR DI,DIdo2:MOV AL,DS:BYTE PTR [SI-1]MOV ES:BYTE PTR DATA2[DI],AL ;先给DATA2中赋值,使其等于输入的数据INC DIDEC SILOOP do2MOV CX,DIXOR SI,SIXOR DI,DIdo3:MOV AL,ES:BYTE PTR DATA2[DI]MOV DS:BYTE PTR [SI],ALINC DI ;再将DATA1中的数据实现,高位存放在地址较大的存储单元INC SILOOP do3s2:XOR AX,AXCALL FAR PTR FAC ;调用阶乘计算函数CMP SI,1 ;当还没有计算到1时,再次进入阶乘函数JNZ s2MOV AL,DS:BYTE PTR [SI-1]CMP AL,1JZ s3JMP s2s3:CALL FAR PTR RESULT ;输出结果JMP s1error:MOV DX,OFFSET STR2STROUTJMP s1exit:MOV DX,OFFSET STR5STROUTMOV AH,4CHINT 21HCODES1 ENDS;*********************************************************CODES2 SEGMENTASSUME CS:CODES2,DS:DATAS,SS:STACKS,ES:DATAS2;递归子过程,计算阶乘,没当递归次数大于等于5000时,返回再次进入,降低栈对递归的限制FAC PROC FARINC AXPUSH AXdo6:MOV AL,ES:BYTE PTR DATA2[DI-1]DEC DICMP AL,0JZ do6INC DICMP DI,CONST2JB s4CALL FAR PTR DZEROs4:CMP SI,1JNZ s5MOV AL,DS:BYTE PTR [SI-1]CMP AL,1JZ s9JMP s6s5:MOV CX,SIDEC CXXOR BP,BPMOV AL,DS:BYTE PTR [BP]SUB AL,1PUSHFAASMOV DS:BYTE PTR [BP],ALdo4:INC BPMOV AL,DS:BYTE PTR [BP]POPFSBB AL,0PUSHFAASMOV DS:BYTE PTR [BP],ALLOOP do4POPFMOV AL,DS:BYTE PTR [SI-1]CMP AL,0JNZ s7DEC SIJMP s7s6:MOV AL,DS:BYTE PTR [SI-1]SUB AL,1MOV DS:BYTE PTR [SI-1],ALs7:CALL FAR PTR MULTPOP AXCMP AX,1388HJZ s8CALL FAR PTR FACs8:RETs9:POP AXRETFAC ENDPCODES2 ENDS;*********************************************************;乘法运算函数,用于多位非压缩码BCD数(DATA1)与多位非压缩码BCD数(DATA2)的乘法运算;,并将结果存放在DATA2中。

10000的阶乘的算法(大数的阶乘)

10000的阶乘的算法(大数的阶乘)

10000的阶乘的算法(⼤数的阶乘)很多天没有更新⾃⼰的Blog了,前⼏天拿到⼀个题⽬.就是写⼀段程序计算10000的阶乘.当时我还以为这题⽬⾮常简单,没想到还是需要动点⼤脑的.花了将近半个⼩时才搞定,拿出来分享⼀下.为什么不能⽤普通的⽅法来写呢,⽐如说递归?在我的教科书上可是⽤的是递归呀?不知道你注意没有,如果是100的阶乘的话,其结果肯定是⾮常⼤的,以我们现有语⾔的数据类型肯定是没法使⽤的,就拿C来说,long型能存的下100的阶乘吗?未必.所以我就使⽤数组来存储结果的每⼀位,然后输出每⼀位不就是结果吗.那么具体怎样去做?⾸先确定结果的位数?如何确定呢?请看下⾯.2!=1*2<=10*103!=1*2*3<=10*10*10.......所以我们可以得出⼀个结论n!<=10n所以n!的位数可以这样计算:两边取对数,即log10n!<=log1010n两边n>=Log101+Log102+Log10 3+....Log10 n这样n!的位数肯定等于⼩于Log101+Log102+Log10 3+....Log10 n.以上是错误的正确的推断如下:可以将n!表⽰成10的次幂,即n!=10^M(10的M次⽅)则不⼩于M的最⼩整数就是 n!的位数,对该式两边取对数,有 =log10^n!即:M = log10^1+log10^2+log10^3...+log10^n循环求和,就能算得M值,该M是n!的精确位数。

位数的确定解决之后,就看看如何计算了.看看如下代码:1int index=0;2long carrier=0;3double bitCount = 1;4int begin = 0;56for(index=2; index<=n; ++index)7 {8long multiValue = 0;9 bitCount += log10((long double)index);10if(arrValue[begin] == 0)11 begin++;1213for(int j=begin; j<int(bitCount); ++j)14 {15 multiValue += (index*arrValue[j]);16 arrValue[j] = char(multiValue % 10);17 multiValue /= 10;18 }19 }这⾥就是计算的关键了.注意⼀下进位问题即可.所有代码如下:12//////////////////////////////////////////////////////////////////////////3// Date created: 2005/07/124// Author: Confach Zhang5// Purpose: 计算n!的值6//////////////////////////////////////////////////////////////////////////789using namespace std;10#include "StdAfx.h"11#include <iostream.h>12#include <conio.h>13#include <stdlib.h>14#include <math.h>15#include <stdio.h>16#include <iomanip.h>1718int GetNumber(); //输⼊ n19int GetBitLength(int n); //求n!的位数20char* Initialize(int); //初始化存储结果的值21void PrintValue(char *a,int size); //打印值到屏幕22void PrintValue(char *a,int size,char* fileName); //打印值到⽂件 23char* GetValue(int val); //计算24char* SubGetValue(char* ,int);252627int main()28{29int value=GetNumber();30char fileName[16];31int size=GetBitLength(value);32char *pa = Initialize(size);3334//pa=GetValue();35 pa=GetValue(value);3637 PrintValue(pa,size);3839//sprintf(fileName,"%s","10000!.txt");40 sprintf(fileName,"%d!.txt",value);4142 PrintValue(pa,size,fileName);43 delete []pa; //note:44return 1;45}46//函数GetValue47// 求得计算结果48//返回结果49//History:50//1)char* GetValue()51//2)GetValue(int val)52// 参数:val 计算阶乘的值53char* GetValue(int val)54{55//定义⼀个数组存储阶乘的值56 //⾸先得到10000!阶乘的位数57int VALUE=val;58int length=GetBitLength(VALUE);59char *arrValue = new char[length];60if(!arrValue) {61 cout <<"申请内存失败!" << endl;62 exit(1);63 }64 arrValue[0] = 1;65for(int i=1; i<length; i++)66 arrValue[i] = 0;67 arrValue=SubGetValue(arrValue,VALUE);68return arrValue;69}7071char* SubGetValue(char* arrValue,int n)72{73int index=0;74long carrier=0;75double bitCount = 1;76int begin = 0;7778for(index=2; index<=n; ++index)79 {80long multiValue = 0;81 bitCount += log10((long double)index);82if(arrValue[begin] == 0)83 begin++;8485for(int j=begin; j<int(bitCount); ++j)86 {87 multiValue += (index*arrValue[j]);88 arrValue[j] = char(multiValue % 10);89 multiValue /= 10;90 }91 }92return arrValue;93}9495//得到计算阶乘的值,此函数为新增96int GetNumber()97{98int n;99 cout << "请输⼊要计算阶乘的n值: ";100 cin >> n;101while(n < 0) {102 cout << "输⼊错误,请重新输⼊: ";103 cin >> n;104 }105if(n == 0)106 exit(1);107return n;108}109110//函数GetBitLength111// 求得计算结果的位数,本函数为新增加112//参数113// n 需要计算的阶乘的数114//返回结果的位数115int GetBitLength(int n)116{117double sum = 1.0;118for(int i=1; i<=n; i++)119 sum += log10((long double)i);120return int(sum);121}122//-----------123//函数:Initialize124// 初始化存储结果的数组125//参数:126// size 数组的长度127//返回值128// 初始化后的数组129//-------------130char * Initialize(int size)131{132char *arrValue = new char[size];133if(!arrValue) {134 cout << size<<"太⼤,申请内存失败!" << endl; 135 exit(1);136 }137 arrValue[0] = 1;138for(int i=1; i<size; i++)139 arrValue[i] = 0;140return arrValue;141}142143//-----------144//函数:PrintValue145// 将结果输⼊到屏幕上146//参数:147// buff 存储结果的数组148// buffLen 数组的长度149// fileName ⽂件名150//-------------151void PrintValue(char *buff, int buffLen)152{153int bit = 0;154int nCol=0;155for(int i=buffLen-1; i>=0; i--) {156if(bit % 10 == 0)157 {158 cout << " " ;159 nCol++;160if(nCol==10)cout<<endl;161 }162 cout << int (buff[i]);163 bit++;164 }165 cout << endl;166167}168//-----------169//函数:PrintValue170// 将结果输⼊到⼀个⽂件中171//参数:172// buff 存储结果的数组173// buffLen 数组的长度174// fileName ⽂件名175//-------------176177void PrintValue(char *buff,int buffLen,char *fileName) 178{179int bit = 0;180int nCol=0;181182 FILE *fp=NULL;183//-----------------------------184185if (fileName==NULL) return ;186 fp=fopen(fileName,"wt");187if (fp==NULL)188 {189 printf("不能创建⽂件%s",fileName);190return ;191 }192193for(int i=buffLen-1; i>=0; i--)194 {195 fprintf(fp,"%d",int(buff[i]));196197if(bit % 9 == 0)198 {199 fprintf(fp,"%s"," ");200 nCol++;201if(nCol==8)202 {203 fprintf(fp,"%s","\n");204 nCol=0;205 }206 }207 bit++;208209 }210 fprintf(fp,"\n");211 fclose(fp);212}213好了,不说了.Last Updated: 2005年7⽉14⽇12:43:07 感谢的建议Last Updated: 2005年7⽉15⽇ 8:48:20 感谢的精彩建议posted on 2005-07-14 12:17 阅读(1260) 所属分类:re: 10000的阶乘 2005-07-14 12:34@Milestone能写多点⽂字吗?⽐如说说,⽤普通的递归会出现什么问题和不⾜你的这种新⽅法的原理是什么,关键的技术点⼜在哪?这样⼀堆代码,我真的看不懂,可能我技术太菜了;)*¥—#**re: 10000的阶乘 2005-07-14 12:36@kwklover谢谢你的提议,有空我写上.re: 10000的阶乘 2005-07-14 13:13普通的递归不⾏猜想原因是C的标准数据类型有可能不能保存结果那么⼤的数值。

计算整数的阶乘(Python)

计算整数的阶乘(Python)

计算整数的阶乘(Python)阶乘是一个自然数逐渐减小并相乘的过程。

对于整数n,其阶乘表示为n!,定义为所有小于或等于n的正整数的积。

计算整数的阶乘是一项非常基础的数学运算,同时也是编程中常见的问题之一。

在本文中,我们将介绍如何使用Python编程语言来计算整数的阶乘,并对阶乘的相关知识进行一些拓展和探讨。

首先,我们来介绍一下如何使用Python来计算整数的阶乘。

Python是一种简洁而强大的编程语言,对于小到中等规模的计算问题,它非常适用。

计算整数的阶乘正是其中之一。

在Python中,可以使用递归或循环的方式来计算整数的阶乘。

首先,我们来看一下使用递归的方法。

递归是一种函数直接或间接调用自身的编程技巧,对于阶乘这种问题,递归的解决方案非常简洁明了。

下面是一个使用递归来计算整数阶乘的Python代码:```pythondef factorial_recursive(n):if n == 1:return 1else:return n * factorial_recursive(n-1)```上面这段代码定义了一个名为`factorial_recursive`的函数,该函数接受一个整数n作为参数,并返回n的阶乘。

在函数体内部,我们使用了`if`语句来判断n是否等于1,如果是,则返回1;如果不是,则返回n与`factorial_recursive(n-1)`的乘积。

这样,就可以通过递归的方式来不断地将n减小,直到计算出1的阶乘,从而得到整个阶乘的结果。

除了递归,我们还可以使用循环的方式来计算整数的阶乘。

下面是一个使用循环来计算整数阶乘的Python代码:```pythondef factorial_iterative(n):result = 1for i in range(1, n+1):result *= ireturn result```在这段代码中,我们定义了一个名为`factorial_iterative`的函数,接受一个整数n作为参数,并返回其阶乘。

c的阶乘计算例子

c的阶乘计算例子

c的阶乘计算例子c语言中,阶乘是一种常见的数学运算,用于计算一个数的阶乘。

阶乘的定义是:n的阶乘(n!)表示从1到n所有正整数的乘积。

下面是一些使用c语言计算阶乘的例子,每个例子都使用了不同的方法或技巧来计算阶乘。

1. 使用for循环计算阶乘:```#include <stdio.h>int factorial(int n) {int result = 1;for (int i = 1; i <= n; i++) {result *= i;}return result;}int main() {int n = 5;int result = factorial(n);return 0;}```这个例子使用了for循环来计算阶乘。

通过遍历从1到n的所有数,将它们相乘得到阶乘的结果。

2. 使用递归计算阶乘:```#include <stdio.h>int factorial(int n) {if (n == 0) {return 1;} else {return n * factorial(n - 1);}}int main() {int n = 5;int result = factorial(n);return 0;}```这个例子使用了递归来计算阶乘。

当n等于0时,阶乘的结果为1;否则,阶乘的结果为n乘以n-1的阶乘。

3. 使用while循环计算阶乘:```#include <stdio.h>int factorial(int n) {int result = 1;int i = 1;while (i <= n) {result *= i;i++;}return result;}int main() {int n = 5;int result = factorial(n);printf("%d的阶乘是:%d\n", n, result);return 0;}```这个例子使用了while循环来计算阶乘。

汇编子程序设计阶乘

汇编子程序设计阶乘

汇编子程序设计阶乘汇编语言是一种底层的程序语言,用于编写机器指令的程序。

子程序设计是汇编语言的一个重要概念,用于将程序模块化以便重复使用。

阶乘是一个经典的数学问题,定义为对于正整数n,阶乘的值表示为n!,等于从1到n的所有正整数相乘的结果。

例如,5!=5×4×3×2×1=120。

在汇编语言中,实现阶乘可以通过递归或迭代的方式完成。

下面我们将详细讨论这两种方法。

一、递归方式实现阶乘:递归方式是一种将问题分解为更小规模的子问题的编程技术。

在实现阶乘时,可以通过递归方式计算出n-1的阶乘,然后将结果与n相乘得到n。

以下是使用递归方式实现阶乘的汇编代码示例:```assemblysection .dataresult db 1section .textglobal _start_start:mov eax, 5call factorialmov [result], eax;此处可添加输出结果的代码mov eax, 1int 0x80factorial:push ebpmov ebp, espmov eax, [ebp+8] ; 读取传入的参数n cmp eax, 1jle end_factorialdec eaxpush eaxcall factorialpop eaximul eax, [ebp+8] ; 计算阶乘结果end_factorial:mov esp, ebppop ebpret```以上代码中,_start是程序的入口点。

我们传入参数5给阶乘的子程序,然后将结果存储在result变量中。

请注意,在第一个call指令后,我们将使用eax寄存器存储结果。

factorial是计算阶乘的子程序。

我们通过比较n是否小于等于1来确定是否终止递归。

如果n大于1,则我们将n减1,并将其压入栈中作为下一次递归的参数。

然后,我们通过调用相同的子程序计算n-1的阶乘结果。

c语言填空题求n的阶乘程序

c语言填空题求n的阶乘程序

c语言填空题求n的阶乘程序阶乘是指将一个正整数 n 与 n-1、n-2、n-3...1 相乘,即 n! = n * (n-1) * (n-2) * ... * 1。

编写一个 C 语言程序,通过填空的方式求给定正整数 n 的阶乘。

下面是完整的代码:```c#include <stdio.h>long long factorial(int n) {long long result = 1;for(int i = 1; i <= n; i++) {result *= i;}return result;}int main() {int n;printf("请输入一个正整数:");scanf("%d", &n);long long result = factorial(n);printf("%d的阶乘是:%lld\n", n, result);return 0;}```在这个程序中,我们使用了一个名为 factorial 的函数来计算阶乘。

该函数接受一个整数参数 n,并返回一个 long long 类型的结果。

在主函数 main 中,我们首先定义了一个整数变量 n,用于存储用户输入的正整数。

然后通过 scanf 函数向用户请求输入一个正整数,并将其保存到变量 n 中。

接下来,我们调用 factorial 函数,传入变量 n 作为参数,并将返回的结果保存到变量 result 中。

最后,使用 printf 函数打印出计算得到的阶乘结果。

这个程序的运行流程如下:1. 用户输入一个正整数。

2. 程序调用 factorial 函数,传入用户输入的正整数,并计算阶乘结果。

3. 阶乘结果被保存在 result 变量中。

4. 程序打印出计算得到的阶乘结果。

注意,本程序使用了 long long 类型来存储阶乘结果,以保证在计算大数阶乘时不会溢出。

阶乘是怎么算的

阶乘是怎么算的

阶乘是怎么算的讲述阶乘是计算一个数的乘积的方法,结果是一个长整数。

它可以有几种不同的写法,但是其原理基本如下:给定一个正整数n,求n阶乘表示为n!,即n! = 1×2×3×...×n。

例如,5阶乘表示为5!,即5! = 1×2×3×4×5 = 120。

阶乘是常用的计算方法,常见于数学表达式中,如阶乘表示采用数学符号n!,表示为n! = 1×2×3×4×...×n。

在计算机科学中,阶乘也有不同种类的应用,如用于求解某数的阶乘,用于求解对应的组合数或定积分等。

从数学上讲,阶乘可以用递归函数来表示,即设f(n) = n * f (n-1),这意味着求n阶乘只需通过计算f(n-1)值就可以求出n!。

例如,要计算 5!,只需求解出f(4),即4! = 24即可得到5! = 120。

Java语言实现阶乘的递归,可写入以下代码://并返回long型的结果public static long factorial(long num){//当我们计算到1时,终止计算if(num==1){return 1;}//通过递归调用计算更小的阶乘return num*factorial(num-1);}计算机中的阶乘也应用于实际问题,最常见的例子是抛硬币,抛n次硬币得到字母A到H,那么求出这种情况下字母ABCD...H出现的概率,应用阶乘即可求解。

例如,假设抛四次硬币,用A、B、C、D表示得到的正面或反面,那么得到ABCD的概率是怎样的呢?答案即为把相应的概率项目乘起来,有:P(ABCD)=P(A)P(B)P(C)P(D)其中,P(A)表示得到A的概率,P(B)表示得到B的概率,P(C)表示得到C的概率,P(D)表示得到D的概率,由于只有正反面,因此P(A) = P(B) = P(C) = P(D) = 1/2。

计算任意整数的阶乘

计算任意整数的阶乘

计算任意整数的阶乘
//1.阶乘也叫階乘,是一个非负整数的函数,这个整数的阶乘是这个数乘以所有小于它的正整数的乘积,直到1,也就是说n的阶乘就是
n!=nx(n-1)x(n-2)x (x2x1)
//2.计算任意整数的阶乘,可以使用循环的方式来实现,可以使用for循环或者while循环,下面给出一个使用for循环实现的阶乘计算代码:
//int factorial (int n)
// int sum = 1;
// for(int i = n; i > 0; i--)
// sum *= i;
// return sum;
//}
//上面的代码使用for循环,从输入的n开始,逐渐减小,直到1,将这每一次的结果相乘,就得到了n的阶乘结果。

//3.另外,还有一种更简单的方法来实现计算任意整数的阶乘,这种方法叫做递归,即一个函数调用自身来实现。

下面给出一个使用递归实现的阶乘计算代码:
//int factorial (int n)
//if (n == 1)
//return 1;
//return n * factorial(n-1);
//}
//上面的代码使用了递归,当n等于1的时候,就返回1,否则就调
用自身来递归计算,直到n等于1时停止,然后将计算的结果按顺序相乘,就得到了n的阶乘结果。

//4.不论使用什么方法实现,需要注意的是,0的阶乘为1,负数的
阶乘没有意义,因此不能计算负数的阶乘。

//总之,任意整数的阶乘可以使用循环的方式或者递归的方式来实现,这两种方式都可以得到一个序列,将这个序列中的每一个数相乘,就能得
到任意整数的阶乘。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

本程序作者cabbage功能:计算1亿以内数的阶乘E-mail:1225673051@;**********************求阶乘程序,十进制输入一个数,十进制输出其结果*********************STROUT MACRO ;宏,DOS功能调用,设置字符串输出入口参数MOV AH,09HINT 21HENDMCHAR_IN MACRO ;宏,DOS功能调用,设置字符输入入口参数MOV AH,01HINT 21HENDMDATAS SEGMENT PUBLICDATA1 DB 10H DUP(0)LEN1 DW ?LEN2 DW ?CONST1 DW 30CONST2 DW 40INDEX DB 10H DUP(0)STR0 DB '********************FACTORIAL**********************$'STR1 DB 0AH,0DH,'Please input the num:$'STR2 DB 0AH,0DH,'Error!$'STR3 DB 0AH,0DH,'The result is:$'STR4 DB 0AH,0DH,'****************************************************$'STR5 DB 0AH,0DH,'Thank you for using!$'DATA3 DB 0FF24H DUP(0)DATAS ENDSDATAS1 SEGMENT PUBLICDB 0FFFFH DUP(0)DATAS1 ENDSDATAS2 SEGMENT PUBLICDATA2 DB 0FFFFH DUP(0)DATAS2 ENDSDATAS3 SEGMENT PUBLICDB 0FFFFH DUP(0)DATAS3 ENDSSTACKS SEGMENT STACKDW 2000H DUP(?)TOP LABEL WORDSTACKS ENDSCODES1 SEGMENTASSUME CS:CODES1,DS:DATAS,SS:STACKS,ES:DATAS2START:MOV AX,DATASMOV DS,AXMOV AX,STACKSMOV SS,AXMOV AX,DATAS2MOV ES,AXMOV SP,OFFSET TOPMOV LEN1,OFFSET DATA2MOV LEN2,OFFSET DATA3MOV DX,OFFSET STR0STROUTs1:CALL ZERO ;清零DATA1,DATA2,DATA3,INDEX,为保证运行结果不受前次影响XOR AX,AXXOR BX,BXXOR CX,CXXOR DX,DX ;清零AX,BX,CX,DX等寄存器,为保证运行结果不受前次影响MOV DX,OFFSET STR1STROUTXOR SI,SIdo1:CHAR_INCMP AL,0DHJZ d1CMP AL,'0'JB errorCMP AL,'9'JA errorSUB AL,'0'MOV DS:BYTE PTR [SI],AL ;输入原始数据,按位输入,高位先输INC SIJMP do1d1:CMP SI,0JZ exitMOV CX,SIXOR DI,DIdo2:MOV AL,DS:BYTE PTR [SI-1]MOV ES:BYTE PTR DATA2[DI],AL ;先给DATA2中赋值,使其等于输入的数据INC DIDEC SILOOP do2MOV CX,DIXOR SI,SIXOR DI,DIdo3:MOV AL,ES:BYTE PTR DATA2[DI]MOV DS:BYTE PTR [SI],ALINC DI ;再将DATA1中的数据实现,高位存放在地址较大的存储单元INC SILOOP do3s2:XOR AX,AXCALL FAR PTR FAC ;调用阶乘计算函数CMP SI,1 ;当还没有计算到1时,再次进入阶乘函数JNZ s2MOV AL,DS:BYTE PTR [SI-1]CMP AL,1JZ s3JMP s2s3:CALL FAR PTR RESULT ;输出结果JMP s1error:MOV DX,OFFSET STR2STROUTJMP s1exit:MOV DX,OFFSET STR5STROUTMOV AH,4CHINT 21HCODES1 ENDS;*********************************************************CODES2 SEGMENTASSUME CS:CODES2,DS:DATAS,SS:STACKS,ES:DATAS2;递归子过程,计算阶乘,没当递归次数大于等于5000时,返回再次进入,降低栈对递归的限制FAC PROC FARINC AXPUSH AXdo6:MOV AL,ES:BYTE PTR DATA2[DI-1]DEC DICMP AL,0JZ do6INC DICMP DI,CONST2JB s4CALL FAR PTR DZEROs4:CMP SI,1JNZ s5MOV AL,DS:BYTE PTR [SI-1]CMP AL,1JZ s9JMP s6s5:MOV CX,SIDEC CXXOR BP,BPMOV AL,DS:BYTE PTR [BP]SUB AL,1PUSHFAASMOV DS:BYTE PTR [BP],ALdo4:INC BPMOV AL,DS:BYTE PTR [BP]POPFSBB AL,0PUSHFAASMOV DS:BYTE PTR [BP],ALLOOP do4POPFMOV AL,DS:BYTE PTR [SI-1]CMP AL,0JNZ s7DEC SIJMP s7s6:MOV AL,DS:BYTE PTR [SI-1]SUB AL,1MOV DS:BYTE PTR [SI-1],ALs7:CALL FAR PTR MULTPOP AXCMP AX,1388HJZ s8CALL FAR PTR FACs8:RETs9:POP AXRETFAC ENDPCODES2 ENDS;*********************************************************;乘法运算函数,用于多位非压缩码BCD数(DATA1)与多位非压缩码BCD数(DATA2)的乘法运算;,并将结果存放在DATA2中。

将多位数乘法运算转变成多位数加法来运行CODES3 SEGMENTASSUME CS:CODES3,DS:DATAS,SS:STACKS,ES:DATAS2MULT PROC FARPUSH AXPUSH BXPUSH CXPUSH DXPUSH BPPUSH SIPUSH DIPOP DXPOP CXXOR DI,DIXOR BP,BPPUSH CXs10:POP CXPUSH CXPUSH BPXOR SI,SIs11:MOV BH,0MOV AH,0MOV BL,DS:BYTE PTR [SI]MOV AL,ES:BYTE PTR DATA2[DI]INC SIMUL BLAAM ;BCD调整指令PUSH BPMOV BL,AHXOR AH,AHADD AL,DS:BYTE PTR DATA3[BP]AAA ;BCD调整指令ADD BL,AH ;可能产生进位MOV DS:BYTE PTR DATA3[BP],ALINC BPMOV AL,BLs12:XOR AH,AHADD AL,DS:BYTE PTR DATA3[BP]AAA ;BCD调整指令MOV DS:BYTE PTR DATA3[BP],ALINC BPMOV AL,AHCMP AL,0JNZ s12POP BPINC BPCMP SI,CXJNZ s11INC DIMOV CX,BPPOP BPADD BP,1CMP DI,DXJNZ s10XOR BP,BPXOR DI,DIdo5:MOV AL,DS:BYTE PTR DA TA3[BP]MOV ES:BYTE PTR DATA2[DI],ALMOV DS:BYTE PTR DATA3[BP],0INC DIINC BPLOOP do5POP SIPOP BPPOP DXPOP CXPOP BXPOP AXRETMULT ENDPCODES3 ENDS;*********************************************************;结果输出函数,将以非压缩BCD码存放的结果转换成科学计数法,并以字符输出CODES4 SEGMENTASSUME CS:CODES4,DS:DATAS,SS:STACKS,ES:DATAS2RESULT PROC FARPUSH DXPUSH DIMOV CX,DIPUSH CXXOR SI,SIXOR BP,BPdo7:MOV AL,ES:BYTE PTR DATA2[DI-1]ADD AL,30HMOV DS:BYTE PTR DATA3[SI],AL ;将DATA2中存放的数以逆序传到DATA3中,并转换成ASCII码DEC DIINC SILOOP do7MOV DS:BYTE PTR DATA3[SI],'$'MOV DX,OFFSET STR3CMP SI,20JA s13MOV DX,LEN2STROUTJMP s14s13:MOV DS:BYTE PTR DATA3[11],'$'MOV DL,DS:BYTE PTR DATA3[BX]MOV AH,02HINT 21HMOV DL,'.'MOV AH,02HINT 21HMOV DX,LEN2INC DX ;第一位已经输出了STROUTMOV DL,'e'MOV AH,02HINT 21HMOV DL,'+'MOV AH,02HINT 21HSUB SI,1MOV CX,SI ;存放现有数据的长度CALL FAR PTR ADDSMOV BX,OFFSET INDEXMOV CX,10HMOV SI,CXdo8:MOV AL,DS:BYTE PTR [BX][SI-1]DEC CXDEC SICMP AL,0JZ do8INC CXINC SIdo9:MOV DL,DS:BYTE PTR [BX][SI-1]ADD DL,30HMOV AH,02HDEC SIINT 21HLOOP do9s14:MOV DX,OFFSET STR4STROUTPOP CXPOP DIPOP DXRETRESULT ENDPCODES4 ENDS;*********************************************************;清零DA TA1,DA TA2,DATA3,INDEX,为保证运行结果不受前次影响CODES5 SEGMENTASSUME CS:CODES5,DS:DATAS,SS:STACKS,ES:DATAS2ZERO PROC FARPUSH DXMOV CX,10HXOR SI,SIdo10:MOV DS:BYTE PTR [SI],0MOV DS:BYTE PTR INDEX[SI],0INC SILOOP do10MOV CX,0FF00HXOR SI,SIdo11:MOV ES:BYTE PTR DATA2[SI],0MOV DS:BYTE PTR DATA3[SI],0INC SILOOP do11POP DXRETZERO ENDPCODES5 ENDS;*********************************************************;在运行的过程中,当DATA2中的结果位数很大时,选择性保留固定长度的高位,将舍弃的位数加到指数INDEX上CODES6 SEGMENTASSUME CS:CODES6,DS:DATAS,SS:STACKS,ES:DATAS2DZERO PROC FARPUSH DXPUSH CXPUSH BXPUSH AXPUSH SIMOV CX,DISUB CX,CONST1MOV DI,CXPUSH DIPUSH CXCALL FAR PTR ADDSPOP CXPOP DIXOR SI,SIdo12:MOV ES:BYTE PTR DATA2[SI],0INC SILOOP do12MOV CX,CONST1XOR SI,SIdo13:MOV AL,ES:BYTE PTR DATA2[DI]MOV ES:BYTE PTR DATA2[SI],ALMOV ES:BYTE PTR DATA2[DI],0INC SIINC DILOOP do13MOV DI,CONST1POP SIPOP AXPOP BXPOP CXPOP DXRETDZERO ENDPCODES6 ENDS;*********************************************************;结果的幂的控制函数,CX为传递参数,存放的是在DZERO去零数CODES7 SEGMENTASSUME CS:CODES7,DS:DATAS,SS:STACKS,ES:DATAS2ADDS PROC FARPUSH BXPUSH AXPUSH BPPUSH SI;CX已经在被调用前赋值do14:XOR AH,AHXOR SI,SIMOV AL,DS:BYTE PTR INDEX[SI]ADD AL,1AAA ;BCD调整指令MOV BL,AH ;可能产生进位MOV DS:BYTE PTR INDEX[SI],ALINC SIMOV AL,BLCMP AL,0JZ s17s16:XOR AH,AHADD AL,DS:BYTE PTR INDEX[SI]AAA ;BCD调整指令MOV DS:BYTE PTR INDEX[SI],ALINC SIMOV AL,AHCMP AL,0JNZ s16s17:LOOP do14POP SIPOP BPPOP AXPOP BXRETADDS ENDPCODES7 ENDSEND START。

相关文档
最新文档