[汇编语言]子程序设计之多精度十进制加法

实验内容:

(1)将两个多精度十进制数相加。
(2)编写一个程序,他以二进制形式显示EAX中32位数据,并设计一个主程序验证。
(3)利用十六进制字节显示子程序DISPHB设计一个从低地址到高地址逐个字节显示某个主存区域内容的子程序DISPMEM。其入口参数:EAX=主存偏移地址,ECX=字节个数主存区域的长度。

实验要求:

1、 要求被加数和加数均以组合BCD码形式各自存放在以DATA1和DATA2为首的连续的5个内存单元中,结果送回被加数单元。
2、 设计一个子程序能够用ASCII码显示32位二进制 3、 设计一个子程序能够用ASCII码从低字节到高字节逐个显示。

实验代码

; six.asm in Windows Console
;将两个多精度十进制数相加
;要求被加数和加数均以组合BCD码形式
;各自存放在以DATA1和DATA2为首的连续的5个内存单元中
;结果送回被加数单元
	include io32.inc
	.data
data1 byte 16h,35h,30h,38h,32h;定义多字节十进制数,以BCD码形式存放
data2 byte 36h,35h,30h,38h,32h;定义多字节十进制数,以BCD码形式存放
count1 = 5;计算被加数BCD码组有多少字节存放
count2 = 5;计算加数BCD码组有多少字节存放

msg1  byte   13,10,'The augend is: ',0
msg2  byte   13,10,'The addend is: ',0
result  byte 13,10,'The result is: ',0

	.code
start:
 
  ;显示被加数
  mov esi,offset data1;si指向被加数首单元
  mov ebx,count1;被加数BCD码组有多少字节表示即被加数多少位
  mov eax,offset msg1;
  call dispmsg;显示被加数
  call dispascii;用ASCII显示被加数
  call dispcrlf;换行
  ;显示加数
  mov esi,offset data2;esi指向加数首单元
  mov ebx,count2;加数BCD码组有多少字节表示即被加数多少位
  mov eax,offset msg2
  call dispmsg
  call dispascii;用ASCII显示加数
  call dispcrlf;换行
  ;做加法
  mov esi,offset data1;si指向被加数首单元
  mov edi,offset data2;di指向加数首单元
  mov ecx,count1;BCD组数传送ecx
  call adda;调用加法子程序
  ;显示和处理结果
  mov esi,offset data1;esi指向结果首单元
  mov ebx,count1;bcd组数
  mov eax,offset result
  call dispmsg
  call dispascii;显示结果ascii
  call dispcrlf;换行
	exit 0
;子程序名:dispascii
;功能:用ascii形式显示多组BCD数
;入口参数:esi指向数据串首单元,ebx存放BCD码组字节数
;无出口参数
dispascii proc near
          add esi,ebx;esi指向数据串最后一个字符
          dec esi;esi指向最后一字节BCD码首位(高位)
          mov ecx,ebx;表示BCD多少字节即循环数
     des: mov dl,[esi];取最后一个字节送至dl,即最后一组BCD码
          mov al,dl;复制dl内容存入al
          shr al,4;al中内容右移四位,得到字节中的高四位
          or  al,30h;加30h转换为ascii码
          call dispc;显示字符,al=ascii码
          and dl,0fh;得到字节中的低四位
          or  dl,30h;加30h转换为ascii码
          mov al,dl;将低四位移入al显示
          call dispc;显示字符
          dec esi;调整指针,指向下一字节bcd码
          dec ecx;循环次数减一(字节减1)
          jnz des;如果ecx不为零,则跳转继续循环
          ret
          dispascii endp
;子程序名:adda
;功能:多精度组合bcd数加法
;入口参数:esi指向被加数首单元,edi指向加数首单元,ecx送字节数BCD码组数
;无返回参数
adda      proc near
          clc;把cf清零
      ad: mov al,[esi];取被加数低地址bcd组
          adc al,[edi];与加数相加,结果放置al中
          daa;组合bcd数相加调整变成bcd码/两个16进制数相加AL=37H+35H=6C调整后al=72h
          mov [esi],al;结果送至被加数位置
          inc esi;被加数取下一组bcd
          inc edi;加数取下一组bcd
          loop ad
          ret
          adda endp
          
	end start

eg2:

; six.asm in Windows Console
;将两个多精度十进制数相加
;要求被加数和加数均以组合BCD码形式
;各自存放在以DATA1和DATA2为首的连续的5个内存单元中
;结果送回被加数单元
	include io32.inc
	.data
data1 dword 16h,35h,30h,38h,32h;定义多字节十进制数,以BCD码形式存放
data2 dword 36h,35h,30h,38h,32h;定义多字节十进制数,以BCD码形式存放
count1 = 20;计算被加数BCD码组有多少字节存放
count2 = 20;计算加数BCD码组有多少字节存放

msg1  byte   13,10,'The augend is: ',0
msg2  byte   13,10,'The addend is: ',0
result  byte 13,10,'The result is: ',0

	.code
start:
 
  ;显示被加数和加数
  mov esi,offset data1;si指向被加数首单元
  mov ebx,count1;被加数BCD码组有多少字节表示即被加数多少位
  mov eax,offset msg1;
  call dispmsg;显示被加数
  call dispascii;用ASCII显示被加数
  call dispcrlf;换行
  mov esi,offset data2;si指向加数首单元
  mov ebx,count2;加数BCD码组有多少字节表示即被加数多少位
  mov eax,offset msg2
  call dispmsg
  call dispascii;用ASCII显示加数
  call dispcrlf;换行
  ;做加法
  mov esi,offset data1;si指向被加数首单元
  mov edi,offset data2;di指向加数首单元
  mov ecx,count1;BCD组数传送cx
  call adda;调用加法子程序
  ;显示和处理结果
  mov esi,offset data1;esi指向结果首单元
  mov ebx,count1;bcd组数
  mov eax,offset result
  call dispmsg
  call dispascii;显示结果ascii
  call dispcrlf;换行
	exit 0
;子程序名:dispascii
;功能:用ascii形式显示多组BCD数
;入口参数:esi指向数据串首单元,ebx存放BCD码组字节数
;无出口参数
dispascii proc near
          add esi,ebx;esi指向数据串最后一个字符
          sub esi,4;si指向最后一组BCD码(高位)
     des: ;mov dh,[si];取最后一个字节送至dh,即最后一组BCD码
          mov edx,[esi];取最后一个字节送至dx,即最后一组BCD码
          ;mov al,dh;复制dh内容存入al
          mov eax,edx;复制dx内容存入ax
          shr al,4;al中内容右移四位,得到字节中的高四位
          ;shr eax,4;al中内容右移四位,得到字节中的高四位
          or  al,30h;加30h转换为ascii码
          ;or  eax,00000030h;加30h转换为ascii码
          ;mov  al,byte ptr eax
          call dispc;显示字符,al=ascii码
          and dl,0fh;得到字节中的低四位
          ;add edx,0000000fh;得到字节中的低四位
          or  dl,30h;加30h转换为ascii码
          ;or  edx,00000030h;加30h转换为ascii码
          mov al,dl
          ;mov  al,byte ptr edx;把低四位放置al
          call dispc;显示字符
          sub esi,4;调整指针,指向下一组bcd码
          sub ebx,4;循环次数减一(字节减4)
          jnz des;如果bx不为零,则跳转继续循环
          ret
          dispascii endp
;子程序名:adda
;功能:多精度组合bcd数加法
;入口参数:esi指向被加数首单元,edi指向加数首单元,ecx送字节数BCD码组数
;无返回参数
adda      proc near
          clc;把cf清零
      ad: ;mov al,[esi];取被加数低地址bcd组
          mov eax,[esi];取被加数低地址bcd组
          ;adc al,[di];与加数相加,结果放置al中
          adc eax,[edi];与加数相加,结果放置eax中
          daa;组合bcd数相加调整变成bcd码/两个16进制数相加AL=37H+35H=6C调整后al=72h
          ;mov [si],al;结果送至被加数位置
          mov [esi],eax;结果送至被加数位置
          add esi,4;被加数取下一组bcd
          add edi,4;加数取下一组bcd
          loop ad
          ret
          adda endp
          
	end start

实验体会:

通过实验可以了解子程序的设计以及掌握了数据传送和算术运算指令的使用,特别是清楚了各个指针寄存器的使用,BCD码的转换、知道了数据具体是如何存储的以及如何提取需要字节的数据内容。

写下这篇博客主要是想记录一下做过的实验,写的不好,请多多指教,互相交流,互相学习。

指路->其他实验.

  • 1
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,我会尽力回答你的问题。首先,我需要说明的是,我是一个AI语言模型,没有实际的物理设备,也不支持汇编语言编程。但是,我可以为你提供一个汇编语言的思路,帮助你完成这个任务。 首先,我们需要了解一下二进制数和十进制数之间的转换规则。将一个16位的二进制数转换成十进制数,我们可以采用乘法累加法的方法。具体步骤如下: 1. 从二进制数的最高位开始,依次取出每一位数字。 2. 对于每一个二进制数位,将其乘以对应的权值(即2的幂次方),得到该位的十进制值。 3. 将所有二进制数位的十进制值相加,得到最终的十进制数值。 接下来,我们可以考虑如何用汇编语言实现这个算法。我们可以将这个算法分为两个步骤:输入二进制数和输出十进制数。 首先,我们需要在主程序中输入一个16位的二进制数,并将其存储在一个寄存器中。然后,我们需要将这个二进制数的每一位数字依次压入堆栈中,以便在程序中进行处理。这个过程可以通过循环实现,具体如下: ``` input_binary: ;输入16位二进制数,存储在 AX 寄存器中 mov ah, 1 ;输入字符 mov cx, 16 ;循环计数器 input_loop: ;输入二进制数位 int 21h ;从键盘读取一个字符 cmp al, '0' ;判断是否是 0 jl input_loop ;如果不是 0,重新输入 cmp al, '1' ;判断是否是 1 jg input_loop ;如果不是 1,重新输入 ;将二进制数位存储到堆栈中 push ax ;将二进制数位压入堆栈中 loop input_loop ;循环输入下一位二进制数 ``` 接下来,我们需要编写一个程序,将堆栈中的二进制数转换成十进制数,并将其存储在一个寄存器中。具体实现如下: ``` bin2dec: ;将二进制数位从堆栈中弹出,并将其转换成十进制数 xor ax, ax ;清空寄存器 AX mov bx, 1 ;权值计数器 dec sp ;将堆栈指针指向栈顶 dec sp ;跳过程序返回地址 convert_loop: ;从堆栈中取出二进制数位 pop cx ;将二进制数位从堆栈中弹出 ;将二进制数位乘以对应的权值,并累加到寄存器 AX 中 cmp cx, 1 ;判断二进制数位是否为 1 je add_value ;如果是 1,执行加法操作 jmp next_value ;如果不是 1,跳过加法操作 add_value: ;将权值加到寄存器 AX 中 add ax, bx next_value: ;将权值乘以 2 shl bx, 1 loop convert_loop ;循环处理下一位二进制数 ;将十进制数字存储到 BX 寄存器中 mov bx, ax ret ``` 最后,我们需要在主程序中调用程序,将十进制数输出到屏幕上。具体实现如下: ``` output_decimal: ;调用程序,将二进制数转换成十进制数 call bin2dec ;将十进制数转换成字符串 mov bx, 10 ;除数为 10 xor cx, cx ;清空计数器 CX output_loop: xor dx, dx ;清空寄存器 DX div bx ;将 BX 除以 AX,商存储在 AL 中,余数存储在 AH 中 ;将余数转换成数字字符,并输出到屏幕上 add dl, '0' ;将余数转换成数字字符 mov ah, 2 ;输出字符 int 21h ;输出数字字符 ;判断是否已经除尽 cmp ax, 0 ;如果商为 0,除尽了 jne output_loop ;如果商不为 0,继续除法运算 ;输出换行符 mov dl, 0Ah ;换行符 mov ah, 2 ;输出字符 int 21h ;输出换行符 ``` 这样,我们就完成了一个将16位无符号的二进制数转换成十进制数的汇编语言程序。当然,这只是一个思路,具体的实现可能还需要根据具体的需求进行调整和修改。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值