汇编程序:32位无符号数乘法

【任务】用十六位乘法指令完成三十二位无符号数乘法(结果64位),数据用下面的内存单元提供:

ddata segment
      x1 dw 5678H
      x2 dw 1234H
      y1 dw 0DEF0H
      y2 dw 9ABCH
      xy dw 4 dup (?)
ddata ends

其中,被乘数x=((x2)*2^16)+(x1),即x2是高16位,x1是低16位;乘数y=((y2)*2^16)+(y1),即y2是高16位,y1是低16位。
【分析】
将把32位的被乘数的乘法分别分割成2个16位的数,分别对其进行16位的乘法,然后将得到的4个16位乘法的乘积,按照各自的位相加的最终乘积,如下图:
这里写图片描述
【参考解答】

assume cs:ccode, ds:ddata
ddata segment
      x1 dw 5678H
      x2 dw 1234H
      y1 dw 0DEF0H
      y2 dw 9ABCH
      xy dw 4 dup (?)
ddata ends
ccode segment
start:mov ax,ddata
      mov ds,ax

      mov ax,x1
      mov dx,y1
      mul dx
      mov [xy],ax
      mov [xy+2],dx     ;被乘数低位4字符x1和乘数低位4字符y1相乘结果低位存入xy,高位存入xy+2

      mov ax,x2
      mov dx,y1
      mul dx
      add [xy+2],ax
      adc [xy+4],dx      ; 被乘数高位4字符x2和乘数低位4字符y1相乘结果低位存入xy+2,高位存入xy+4

      mov ax,x1
      mov dx,y2
      mul dx
      add [xy+2],ax
      adc [xy+4],dx
      adc [xy+6],0       ; 被乘数低位4个字符x1和乘数高位4个字符y2相乘结果低位存入xy+2,高位存入xy+4

      mov ax,x2
      mov dx,y2
      mul dx
      add [xy+4],ax
      adc [xy+6],dx      ; 被乘数高位4个字符x2和乘数高位4个字符y2相乘结果低位存入xy+4,高位存入xy+6

      mov ah,4ch
      int 21h

ccode ends
end start
  • 3
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
对于无符号32位乘法,我们可以使用8086汇编语言的MUL指令来完成。MUL指令可以将一个无符号的16位操作与AX寄存器的值相乘,并将结果存储在DX和AX寄存器。因此,我们可以先读取存储在内存的两个16位据,将它们分别存储到AX和BX寄存器,然后执行MUL指令,最后将结果存储到内存。 下面是一个简单的8086汇编语言程序,用于完成32位无符号数乘法: ``` assume cs:code, ds:data data segment num1 dw 1234h ; 第一个16位 num2 dw 5678h ; 第二个16位 result dw 0 ; 结果的低16位 dw 0 ; 结果的高16位 data ends code segment start: mov ax, data mov ds, ax ; 设置DS寄存器 mov ax, [num1] ; 读取第一个16位 mov bx, [num2] ; 读取第二个16位 mul bx ; 将两个16位相乘 mov word ptr [result], ax ; 存储结果的低16位 mov word ptr [result+2], dx ; 存储结果的高16位 ; 其他操作... mov ah, 4ch int 21h ; 退出程序 code ends ``` 对于带符号32位乘法,我们需要先进行符号扩展,将两个16位的带符号扩展为32位的有符号,然后再进行乘法运算。具体来说,我们可以使用SAR指令进行符号扩展,SAR指令可以将一个有符号向右移位,并保留符号位的值。例如,对于一个16位的有符号,我们可以使用SAR指令将它向右移动15位,从而将符号位的值复制到高16位上。然后,我们将扩展后的两个32位有符号存储到DX和AX寄存器,执行MUL指令,最后将结果存储到内存。 下面是一个简单的8086汇编语言程序,用于完成32位带符号数乘法: ``` assume cs:code, ds:data data segment num1 dw -1234h ; 第一个16位(带符号) num2 dw 5678h ; 第二个16位(带符号) result dw 0 ; 结果的低16位 dw 0 ; 结果的高16位 data ends code segment start: mov ax, data mov ds, ax ; 设置DS寄存器 mov ax, [num1] sar ax, 15 ; 将第一个16位符号扩展为32位 cwd ; 将AX的值符号扩展为DX:AX的值 mov bx, [num1] imul bx ; 将第一个带符号扩展为32位有符号 mov ax, [num2] sar ax, 15 ; 将第二个16位符号扩展为32位 cwd ; 将AX的值符号扩展为DX:AX的值 mov bx, [num2] imul bx ; 将第二个带符号扩展为32位有符号 mul bx ; 将两个32位有符号相乘 mov word ptr [result], ax ; 存储结果的低16位 mov word ptr [result+2], dx ; 存储结果的高16位 ; 其他操作... mov ah, 4ch int 21h ; 退出程序 code ends ``` 需要注意的是,在进行带符号数乘法时,我们需要使用IMUL指令来进行乘法运算,IMUL指令可以进行带符号乘法运算,并将结果存储在AX或DX:AX寄存器。同时,我们还需要使用CWD指令将AX寄存器的值符号扩展到DX寄存器

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值