1.1实验内容

实现两个十进制大整数的相乘(100位以上),输出乘法运算的结果。

1.2实验环境

Microsoft Visual Studio 2017+masm 32

1.3实验思路

1.3.1数据读入

大数相乘由于输入的数字过大而不能用一个dword来存储,所以需要使用数组来存取每一位,每一位大小范围在0-9中,按位读取输入,所以首先需要按照字符读取输入,将读入的两个数存储为两个字符数组中。

   ;键盘分别输入A和B,并存储为byte数组invoke printf, offset inputMsginvoke scanf,addr input,addr numCharAinvoke printf,offset inputMsginvoke scanf,addr input,addr numCharB

1.3.2 将字符转为数字并反转存储

由于读入数据的是字符,所以需要先将字符转为数字,才能进行乘法,其次在大数相乘中,我们模拟手算乘法的过程,即乘数之间从低位向高位相乘并按位存储,再进行进位处理。所以,在转换为数字的过程中,我们通过将字符处理为数字后压栈,再依次退栈存储到数字数组中,实现将数字反转,这样再模拟乘法过程中可以从数组开始循环至数组结束。

 invoke strlen,numCharmov len,eaxmov ecx,lenL3:;eax=esi[i]movzx eax,byte ptr[esi];减去'0',得到数字0-9sub eax,30H;压栈push eax;esi=numChar[i+1]inc esiloop L3mov ecx,lenmov esi,numIntL4:;从栈中弹出数据,依次存储到numInt中,达到反序的目的pop eaxmov dword ptr[esi],eax;esi+4,因为numInt为dword数组,4个偏移量为一个数据add esi,4loop L4;再次调用strlen,使eax=len,返回时从eax即可读出len的值invoke strlen,numChar

1.3.3 模拟乘法

模拟乘法的过程为模拟手算乘法的过程,即x的第i位与y的第j位相乘时,结果存储到结果的第i+j位。

  mov ebx, -1
OuterLoop: inc ebxcmp ebx, lengthAjnb endLoop1 ;如果ebx >= lengthA,结束循环xor ecx, ecx
InnerLoop:xor edx, edxmov eax, dword ptr numIntA[4 * ebx]mul numIntB[4 * ecx] ;numIntA[4 * ebx] * numIntB[4 * ecx]结果放在EDX:EAX中,最大9*9 = 81也不会超过8个字节,所以结果只在EAX中mov esi, ecxadd esi, ebx ;esi = ecx + ebx,即两个下标之和add result[4 * esi], eax ;把两个位相乘的结果加到result的相应位上inc ecxcmp ecx, lengthB jnb OuterLoop ;无符号数ecx>=lengthB时,下标超过lengthB - 1时跳出内层循环重新进行外层循环jmp InnerLoop   ;不超过则继续进行内层循环
endLoop1:mov ecx, lengthAadd ecx, lengthBinc ecx ;ecx = lengthA + lengthB + 1mov esi, offset lengthCmov [esi], ecx ;将ecx赋给lengthC

1.3.4 进位

从低位到高位依次将结果的第i+1位加上第i位除10的结果,第i位等于第i位模10的结果。即result[i+1]+=result[i]/10,result[i]+=result[i]%10。

CarryCul:cmp ebx, ecxjnb endLoop2 ;ebx >= ecx跳到endLoop2,跳出求进位的循环mov eax, result[4  * ebx]xor edx, edxdiv radixadd result[4 * ebx + 4], eax ;result[i+1] += result[i]/10mov result[4 * ebx], edx ;result[i] = result[i] % 10inc ebxjmp CarryCul
endLoop2: mov ecx, lengthC ;让MoveZero从最后一位开始检查

1.3.5 清0

当i位数与j位数相乘时,最终结果不一定是i+j位,从最高位依次检测结果数组中的值是否为0,为0则长度减1。

MoveZero:cmp dword ptr result[4 * ecx], 0jnz endwhile1 ;result的末位不为0dec ecx ;每检测到一个0,实际长度减一 jmp MoveZero
endwhile1:inc ecx ;实际长度为最大下标加一mov esi, offset lengthCmov [esi], ecx ;将ecx赋给lengthC

1.3.6结果转为字符再输出

由于计算的结果也是反序存储在结果数组中,所以需要将结果数组反转并且转换位字符数组才能输出,所以采用和1.3.2类似的方法,将数字转为字符并压栈,循环结束后将字符依次退栈存储到结果中,最后输出字符串即可。

int2str_reverse proc far C uses eax esi ecx mov ecx, lengthC ;结果的长度为循环的次数mov esi, 0
L1:mov eax, dword ptr result[4 * esi] add eax, 30H ;数字0~9 + '0'得到字符'0'~'9'push eaxinc esiloop L1 ;把dword数组numInt全部入栈,最高位先入栈,最低位最后入栈mov ecx, lengthCmov esi, 0
L2:pop eaxmov byte ptr resultChar[esi], al ;依次出栈,把低八位存在resultChar的对应位置中,最低位先出栈,存在resultChar的最低位中inc esiloop L2ret
int2str_reverse endp

1.3.6 对负数进行处理

由于读入数据是一个一个字符的读入,所以如果读入的数字第一位为“-”,维护一个negativeFlag初始为0。若读入一个符号,则将其异或,则0变1,再有一个负号则1变0,当negativeFlag为1时,输出时则在结果之间输出负号。

;esi=numChar首地址mov esi,numChar;eax=esi[0]movzx eax,byte ptr[esi];Symbol=eax,判断numChar第一个字符是否为负号mov Symbol,eax.if Symbol==2DH;为负数,negativeFlag异或1xor negativeFlag,1;调用strlen得到numChar的长度invoke strlen,numChar;减去负号sub eax,1mov len,eaxmov ecx,len;esi=numChar[1]inc esi

1.4实验结果

1.5完整代码

Chris_William/BIT-X86-Experiment (gitee.com)https://gitee.com/chris-william/bit-x86-experiment

汇编语言实验——大数相乘相关推荐

  1. 超大数相乘的java代码,java版大数相乘

    在搞ACM的时候遇到大数相乘的问题,在网上找了一下,看到了一个c++版本的 用java搞了一个版本 这里说一下思路 将数字已字符串形式接收,转换成int[]整型数组,然后num1[],num2[]依次 ...

  2. 云南大学信息学院c语言实验七,云南大学软件学院汇编语言实验报告七.docx

    云南大学软件学院汇编语言实验报告七.docx 练习统计男女生人数1.实验内容统计一个有10人的班中,男.女生的人数各为多少.将统计结果的男生人数存入变量MAN中,女生人数存入变量WOMAN中.3.编程 ...

  3. 大数相乘、大数相加、大数相减Java版本

    为什么80%的码农都做不了架构师?>>>    题目:两个非常大的数字相乘(相加,相减) 该题目在java中可以使用BigInteger类中的方法来实现.否则的话可以使用如下方式来实 ...

  4. 大数相乘--极简单的思路

    大数相乘,面试常见的题型,如何计算两个打算相乘? <pre style="font-family: 'Lucida Sans Typewriter'; font-size: 12pt; ...

  5. 汇编语言 实验10.1 显示字符串

    汇编语言 实验10.1 显示字符串 问题 显示字符串是现实生活中经常要用到的功能,应该编写一个通用的子程序来实现这个功能.我们应该提供灵活的调用接口,是调用者可以决定显示的位置(行.列).内容和颜色. ...

  6. C#中关于处理两个大数相乘的问题

    方法一:直接利用.NET FrameWork 4.0中自带的System.Numeric类库 添加了对此类库的引用后,直接调用方法即可计算: View Code 1 BigInteger num1 = ...

  7. 8086汇编学习小记-王爽汇编语言实验12

    8086汇编学习小记-王爽汇编语言实验12 0号中断处理程序,开始安装在0000:0200处的程序最后用死循环导致显示不出'divided error',改成直接退出就正常显示了.注意修改ss,sp之 ...

  8. 大数相乘(c语言/c++)

    大数相乘(c语言/c++) 方法一:做加法 方法二.做乘法 方法一:做加法 思路:模拟竖乘过程.将num2从后往前一个一个的去乘num1.然后累加.在累加的时候记得在末尾补0.补的0的个数就是第二个字 ...

  9. 算法题-大数相乘问题

    今天在网上看到一个大数相乘的问题,题目是这样的:输入两个整数,要求输出这两个数的乘积.输入的数字可能超过计算机内整形数据的存储范围. 分析: 由于数字无法用一个整形变量存储,很自然的想到用字符串来表示 ...

最新文章

  1. Idea开发Java WEB 应用
  2. HAProxy + Keepalived + Flume 构建高性能高可用分布式日志系统
  3. 2020蓝桥杯省赛---java---B---10(整数小拼接)
  4. 第三只眼使用局域网版本还是网络版好_iOS13.4测试版使用3天后,发现3个优化,建议升级!...
  5. outlook阅读html,Outlook HTML邮件中英文混排字体设置
  6. Halcon 轮廓合并算子
  7. 《Spark The Definitive Guide》Spark 权威指南学习计划
  8. 淡定的写代码,淡定的人生
  9. Glide 4.x之生命周期与Activity的绑定原理详解
  10. 算法设计与分析: 3-4 多重幂计数问题
  11. iOS之UITableViewController的使用
  12. ios开发eaaccessory案例_iOS App 连接外设的几种方式
  13. 《平衡掌控者 游戏数值战斗设计》学习笔记(五)物品掉落
  14. Graylog 中文手册 常用功能和问题整理
  15. 太简单!只学十分钟,Python菜鸟也能开发一个区块链客户端
  16. fix indent命令实现纳米摩擦及摩擦力计算案例
  17. AI+医疗:使用神经网络进行医学影像识别分析 ⛵
  18. kubernetes 介绍_Kubernetes的友好介绍
  19. iOS6系统如何升级 菜鸟也能轻松上手
  20. c++常用函数所在头文件一览

热门文章

  1. 如何规范写出 README 模板?
  2. HDU2639 01背包 第K优决策
  3. 洛谷 P7453 [THUSCH2017] 大魔法师
  4. 如何实现集成GB28181监控平台LiveGBS的录像回放时间轴页面
  5. js 手机号、姓名、身份证号脱敏(打星号)
  6. linux的 dev vdb,LVM 操作: /dev/vdb
  7. JFlow工作流项目集成案例_Java开源项目 RuoYi v4.1.0
  8. C++中vector的reverse函数及其用法(详解)
  9. 根服务器 ipv6 位置,ipv6dns根服务器地址
  10. java练习--人机猜拳