汇编语言实验——大数相乘

这篇具有很好参考价值的文章主要介绍了汇编语言实验——大数相乘。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

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 inputMsg
    invoke scanf,addr input,addr numCharA
    invoke printf,offset inputMsg
    invoke scanf,addr input,addr numCharB

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

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

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

1.3.3 模拟乘法

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

  mov ebx, -1
OuterLoop: 
    inc ebx
    cmp ebx, lengthA
    jnb endLoop1 ;如果ebx >= lengthA,结束循环
    xor ecx, ecx
InnerLoop:
    xor edx, edx
    mov 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, ecx
    add esi, ebx ;esi = ecx + ebx,即两个下标之和
    add result[4 * esi], eax ;把两个位相乘的结果加到result的相应位上
    inc ecx
    cmp ecx, lengthB 
    jnb OuterLoop ;无符号数ecx>=lengthB时,下标超过lengthB - 1时跳出内层循环重新进行外层循环
    jmp InnerLoop   ;不超过则继续进行内层循环
endLoop1:
    mov ecx, lengthA
    add ecx, lengthB
    inc ecx ;ecx = lengthA + lengthB + 1
    mov esi, offset lengthC
    mov [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, ecx
    jnb endLoop2 ;ebx >= ecx跳到endLoop2,跳出求进位的循环
    mov eax, result[4  * ebx]
    xor edx, edx
    div radix
    add result[4 * ebx + 4], eax ;result[i+1] += result[i]/10
    mov result[4 * ebx], edx ;result[i] = result[i] % 10
    inc ebx
    jmp CarryCul
endLoop2: 
    mov ecx, lengthC ;让MoveZero从最后一位开始检查

1.3.5 清0

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

MoveZero:
    cmp dword ptr result[4 * ecx], 0
    jnz endwhile1 ;result的末位不为0
    dec ecx ;每检测到一个0,实际长度减一 
    jmp MoveZero
endwhile1:
    inc ecx ;实际长度为最大下标加一
    mov esi, offset lengthC
    mov [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 eax
    inc esi
    loop L1 ;把dword数组numInt全部入栈,最高位先入栈,最低位最后入栈

    mov ecx, lengthC
    mov esi, 0
L2:
    pop eax
    mov byte ptr resultChar[esi], al ;依次出栈,把低八位存在resultChar的对应位置中,最低位先出栈,存在resultChar的最低位中
    inc esi
    loop L2
    ret
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异或1
        xor negativeFlag,1
        ;调用strlen得到numChar的长度
        invoke strlen,numChar
        ;减去负号
        sub eax,1
        mov len,eax
        mov ecx,len
        ;esi=numChar[1]
        inc esi

1.4实验结果

汇编语言实验——大数相乘

汇编语言实验——大数相乘文章来源地址https://www.toymoban.com/news/detail-486030.html

到了这里,关于汇编语言实验——大数相乘的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 《汇编语言》王爽(第四版) 第十章 实验10

    文章目录 前言 一、子程序1 显示字符串 1.实验任务 2.分析 (1)如何在指定位置显示 (2)如何显示指定颜色 (3)保存子程序中用到的寄存器 3.代码 二、子程序2 解决除法溢出的问题 1.实验任务 2.代码 三、子程序3 数值显示 1.实验任务 2.显示一个word型数据的代码 总结 本文是

    2024年02月08日
    浏览(30)
  • 《汇编语言》王爽(第四版)第八章 实验7

    文章目录 前言 一、题目 二、分析 1.内存分配情况 2.数据结构分析 3.实现思路 (1)设置段寄存器 (2)复制“年份”数据 (3)复制“年总收入”数据 (4)复制“雇员人数”数据 (5)计算“人均收入” 三、代码 1.实现代码 2.优化代码 3.最终代码 总结 王爽老师《汇编语言》

    2024年02月04日
    浏览(59)
  • 【汇编语言与微机原理】实验五:键盘按键与数码管显示

    熟悉星研集成开发环境,掌握微机接口程序编写调试的基本方法。 掌握矩阵式键盘工作原理及识别按键的方法。 掌握8段数码管显示数字或字符的工作原理和它的使用方法。 掌握用8255扫描键盘及用8255刷新数码管的显示方法。 在2*8(看 着像4*4,实际上是2*8 )的小键盘上按下

    2024年02月16日
    浏览(29)
  • 实验一8086计CPU系统寻址方式和汇编语言程序设计

    实验一8086计CPU系统寻址方式和汇编语言程序设 一、实验目的 (1)掌握8086CPU系统的逻辑地址和寻址方式。 (2)掌握8086CPU系统中机器数的表示方式。 (3)掌握指令的机器码表示方法。 (4)掌握堆栈的概念和操作过程。 (5)掌握集成开发环境下的程序设计和调试方法。 (6)掌握汇编语言实

    2023年04月22日
    浏览(34)
  • 南京邮电大学汇编语言程序设计实验二(用户登录验证程序的设计)

    1.掌握循环程序的编写以及结束循环的方法。 2.掌握DOS、BIOS功能调用的使用方法。 用户登录验证程序的实现 程序执行后,给出提示操作,请用户键入用户名和密码;用户在键入密码时,程序不回显键入字符;只有当用户键入的用户名,密码字符串和程序内定的字符串相同时

    2023年04月18日
    浏览(41)
  • 汇编语言实验8:BIOS/DOS功能调用与宏指令程序设计

    掌握汇编语言程序设计的基本方法和技能 掌握汇编语言源程序的编辑汇编连接和执行的完整过程 通过上机操作理解宏定义、宏调用、宏展开的概念,熟练运用宏功能编写程序 掌握BIOS/DOS基础功能的实现调用方法 理解常用的DOS功能调用的基本使用,能熟练运用1号,2号,9号,

    2024年02月03日
    浏览(52)
  • 基于Proteus仿真的交通信号灯设计——利用汇编语言实现

    基本信息 采用AT89C51单片机 晶振频率:12MHZ 红绿灯:发光二极管 数字显示:LED数码管 东西南北四个方向,一次循环共有六个状态,且每个状态的倒计时时间一样 交通状态 东西红灯22s,南北绿灯22s(数码管从0到21); 东西红灯5s,南北绿灯5s且没0.5s闪烁一次(数码管从0到4);

    2024年02月09日
    浏览(42)
  • 汇编语言实现C51单片机点亮流水灯

    P0作输出口,接8只发光二极管,编写程序实现二极管循环点亮 二极管为共阳极连接时,即二极管正极已接通电源,单片机输出接阴极,所以单片机输出为低电平有效。 所以为实现二极管轮流点亮,单片机的输出应为:0FEH,0FDH,0FBH,....0FEH,每输出一种状态,需要延时0.1us. 最后在

    2024年02月06日
    浏览(42)
  • 汇编语言笔记(一)——汇编语言基础

    一、开发环境 我使用visual studio 2022 preview,其他版本的设置大同小异。 第一步: 打开visual studio,点击“创建新项目”: 第二步: visual studio并没有专门的汇编项目,所以需要挂羊头卖狗肉,选择C++空项目 第三步: 输入项目名称,点击创建 第四步: 鼠标右键单击项目名称—

    2024年02月05日
    浏览(30)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包