将两个多位十进制数相减,要求被减数,减数均以 ASCII码形式按顺序存放在以DATA1和DATA2为首的5个内存单元中(低位在前),结果送回DATA1处。
这个程序就是实现两个多位数相减功能,经过查阅资料分析得到,有两种方法分别是一位位相减和合成一个整体后再相减。
1.一位位相减要利用sbb带借位的减法实现功能,这样计算得到的结果就是正确的了。其次这种方法,要进行分类讨论,比较被减数和减数的大小才能得到正确的结果。如果减数比被减数大的话要先显示一个负号,再输出结果。
2.合成一个整体麻烦的难点在于要合成一个数,利用汇编语言合成一个数的思路其实是很类似的,只要学会一个其余都问题不大了。
我写了三种,第一种最简单,无符号数,不输入。

DATAS SEGMENT;此处输入数据段代码 A db 4 dup(?)length_A equ $-AB db 4 dup(?)buf1 db '-','$'buf2 db '=','$'buf3 db 'Please input two number:',0dh,0ah,'$'buf4 db 'A=','$'buf5 db 'B=','$'
DATAS ENDSSTACKS SEGMENT;此处输入堆栈段代码dw 50 dup(?)top label byte
STACKS ENDSCODES SEGMENTASSUME CS:CODES,DS:DATAS,SS:STACKS
START:mov ax,stacksmov ss,axmov sp,offset topMOV AX,DATASMOV DS,AX;此处输入代码段代码;A部分;显示A中的数据lea dx,buf4mov ah,09hint 21hmov cx,length_Alea si,Acall inputcall hui_chelea dx,buf5mov ah,09hint 21hmov cx,length_Alea si,Bcall inputcall hui_chemov cx,length_Alea di,ALoop_show_A:mov al,[di]call show_asciiinc diloop Loop_show_Alea dx,buf1mov ah,09hint 21h;B部分;显示B中的数据mov cx,length_Alea di,BLoop_show_B:mov al,[di]call show_asciiinc diloop Loop_show_Blea dx,buf2mov ah,09hint 21h;减法运算部分mov si,offset Amov di,offset B   mov cx,length_A
compare:;比较a和b哪一个数据更大mov al,[si]cmp al,[di]ja a_b;大于的话直接比较jb b_a;小于的话b-aje keep_compare;继续比较下一位
keep_compare:dec cxinc siinc dijmp compare
b_a:mov dl,'-';显示负号mov ah,02hint 21h;应该是b-acall sub_B_Amov si,offset Amov cx,length_Ajmp Loop_show_result
a_b:call sub_A_Bmov si,offset Amov cx,length_A  Loop_show_result:mov al,[si]call show_asciiinc siloop Loop_show_result;结束部分jmp end_proinput proc near
input_loop:mov ah,01hint 21hmov [si],alinc siloop input_loop
exit:ret
input endpshow_ascii proc near;显示ascii码mov dl,almov ah,02hint 21hret
show_ascii endp sub_A_B proc nearmov bx,length_A
su1:sub byte ptr[si+bx-1],30h;最后一位数据,转换为十进制sub byte ptr[di+bx-1],30hdec bxjnz su1mov si,offset Aadd si,length_A-1mov di,offset B   add di,length_A-1mov cx,length_A;包括进位一共有位数clc
su2:mov al,[si]mov bl,[di]sbb al,bl;带借位相减aas;非压缩BCD码格式的调整mov [si],al;结果被送到di作为被减数被减数区域dec sidec di;指向下一位loop su2;循环mov bx,length_Amov si,offset Amov di,offset B
su3:add byte ptr [si+bx-1],30h;add byte ptr [di+bx-1],30hdec bxjnz su3ret
sub_A_B endpsub_B_A proc nearmov bx,length_A
su1:sub byte ptr[si+bx-1],30h;最后一位数据,转换为十进制sub byte ptr[di+bx-1],30hdec bxjnz su1mov si,offset Badd si,length_A-1mov di,offset A   add di,length_A-1mov cx,length_A;包括进位一共有位数clc
su2:mov al,[si]mov bl,[di]sbb al,bl;带借位相减aas;非压缩BCD码格式的调整mov [di],al;结果被送到被减数区域dec sidec di;指向下一位loop su2;循环mov bx,length_Amov si,offset Bmov di,offset A
su3:add byte ptr [di+bx-1],30h;add byte ptr [di+bx-1],30hdec bxjnz su3ret
sub_B_A endphui_che proc nearmov dl,0ahmov ah,02hint 21hret
hui_che endpend_pro:MOV AH,4CHINT 21H
CODES ENDSEND START


第二种和第一种唯一的区别是加入了输入:

DATAS SEGMENT;此处输入数据段代码 A db 33h,38h,39h,36h;3896length_A equ $-AB db 31h,32h,33h,35h;1235buf1 db '-','$'buf2 db '=','$'
DATAS ENDSSTACKS SEGMENT;此处输入堆栈段代码dw 50 dup(?)top label byte
STACKS ENDSCODES SEGMENTASSUME CS:CODES,DS:DATAS,SS:STACKS
START:mov ax,stacksmov ss,axmov sp,offset topMOV AX,DATASMOV DS,AX;此处输入代码段代码;A部分;显示A中的数据mov cx,length_Alea di,ALoop_show_A:mov al,[di]call show_asciiinc diloop Loop_show_Alea dx,buf1mov ah,09hint 21h;B部分;显示B中的数据mov cx,length_Alea di,BLoop_show_B:mov al,[di]call show_asciiinc diloop Loop_show_Blea dx,buf2mov ah,09hint 21h;减法运算部分mov si,offset Amov di,offset B mov cx,length_A
compare:;比较a和b哪一个数据更大mov al,[si]cmp al,[di]jg a_b;大于的话直接比较jb b_a;小于的话b-aje keep_compare;继续比较下一位
keep_compare:dec cxinc siinc dijmp compare
b_a:mov dl,'-';显示负号mov ah,02hint 21h;应该是b-acall sub_B_Amov si,offset Amov cx,length_Ajmp Loop_show_result
a_b:call sub_A_Bmov si,offset Amov cx,length_A  Loop_show_result:mov al,[si]call show_asciiinc siloop Loop_show_result;结束部分jmp end_proshow_ascii proc near;显示ascii码mov dl,almov ah,02hint 21hret
show_ascii endp sub_A_B proc nearmov bx,length_A
su1:sub byte ptr[si+bx-1],30h;最后一位数据,转换为十进制sub byte ptr[di+bx-1],30hdec bxjnz su1mov si,offset Aadd si,length_A-1mov di,offset B   add di,length_A-1mov cx,length_A;包括进位一共有位数clc
su2:mov al,[si]mov bl,[di]sbb al,bl;带借位相减aas;非压缩BCD码格式的调整mov [si],al;结果被送到di作为被减数被减数区域dec sidec di;指向下一位loop su2;循环mov bx,length_Amov si,offset Amov di,offset B
su3:add byte ptr [si+bx-1],30h;add byte ptr [di+bx-1],30hdec bxjnz su3ret
sub_A_B endpsub_B_A proc nearmov bx,length_A
su1:sub byte ptr[si+bx-1],30h;最后一位数据,转换为十进制sub byte ptr[di+bx-1],30hdec bxjnz su1mov si,offset Badd si,length_A-1mov di,offset A   add di,length_A-1mov cx,length_A;包括进位一共有位数clc
su2:mov al,[si]mov bl,[di]sbb al,bl;带借位相减aas;非压缩BCD码格式的调整mov [di],al;结果被送到被减数区域dec sidec di;指向下一位loop su2;循环mov bx,length_Amov si,offset Bmov di,offset A
su3:add byte ptr [di+bx-1],30h;add byte ptr [di+bx-1],30hdec bxjnz su3ret
sub_B_A endpend_pro:MOV AH,4CHINT 21H
CODES ENDSEND START


最后一种是加入了对于有符号数的处理,可以输入并且输出有符号数,直接将减数和被减数相减即可。

DATAS SEGMENT;此处输入数据段代码 buf dw 2 dup(?)tmp db 10 dup(?)buf1 db '-','$'buf2 db '=','$'buf3 db 'Please input two number:',0dh,0ah,'$'buf4 db 'A=','$'buf5 db 'B=','$'buf6 db 0ah,'The character is out of range, Try again:',0dh,0ah,'$'
DATAS ENDSSTACKS SEGMENT;此处输入堆栈段代码dw 50 dup(?)top label byte
STACKS ENDSCODES SEGMENTASSUME CS:CODES,DS:DATAS,SS:STACKS
START:mov ax,stacksmov ss,axmov sp,offset topMOV AX,DATASMOV DS,AX;此处输入代码段代码;A部分;显示A中的数据lea dx,buf4mov ah,09hint 21hmov si,0;si作为下标call prepare_inputcall inputadd si,02hlea dx,buf5mov ah,09hint 21hcall prepare_inputcall input;显示计算数据mov si,0mov ax,buf[si]add si,02hcall show_asciimov dl,'-'mov ah,02hint 21hmov ax,buf[si]call show_asciimov dl,'='mov ah,02hint 21h;减法运算部分mov si,0mov ax,buf[si]add si,02hmov dx,buf[si]sub ax,dxcall show_asciijmp end_proprepare_input proc nearmov bx,10mov bp,0mov dx,0ret
prepare_input endpinput proc nearpush cx
get_char:mov ah,01hint 21hcmp al,'-';判断是否为负数jz nagetivecmp al,0dh;判断是否为回车jz process_1cmp al,' ';判断是否为空格jz process_1cmp al,30hjl mistakecmp al,39h;大于9ja judge1jmp process_2
judge1:cmp al,41h;表示在39<x<41的数jb mistakecmp al,80h;表示>46即超过F的数ja mistakejmp process_2
mistake:mov dx,offset buf6mov ah,9hint 21h jmp get_char
nagetive:mov bp,1;bp作为符号位jmp get_char
process_2:push ax;mov ax,dxmul bx;乘以10,以十进制存储mov dx,ax;数据保存在dx中pop axsub al,30hmov ah,0add dx,axjmp get_char
process_1:cmp bp,1jnz saveneg dx;取负命令0-原数据
save:mov buf[si],dx;将处理好的数据存入num中去mov bp,0;bp位清零    mov dl,0dh;回车换行重新输入mov ah,2int 21hmov dl,0ahint 21h
exit:pop cxret
input endpshow_ascii proc neartest ax,1000h;与命令jz pre_show;不是负数push axmov dl,'-';是负数的情况,先显示负号mov ah,02hint 21hpop axneg ax
pre_show:mov di,0mov dx,0mov bx,10
mid_show:div bx;十六进制转十进制add dl,30h;余数部分作为结果mov tmp[di],dlinc dicmp ax,0;判断商是否为0,是则表示转换完成jz last_showmov dx,0;余数部分清零jmp mid_show
last_show:mov dl,tmp[di-1];dl为待输出字符的ascii码mov ah,2int 21hdec dijnz last_showret
show_ascii endpend_pro:MOV AH,4CHINT 21H
CODES ENDSEND START


用汇编实现一个简单的多位数相减起始挺复杂的,第一种方法的缺点在于,首先减数和被减数的位数要相同,优点在于不用受位数的限制可以输入任意多位而不会发生溢出。方法二的缺点在于输入位数不能超过有符号数的范围,优点相减结果不需要讨论,可以直接输出结果。这个程序也是在一步步的改进中更加完善,起始功能是很简单的,后来增加了输入输出,后面发现没有对有符号数的处理,同样后面也改进了。我默认是输入4位数,后续可以改进的功能是输入任意多位数,以及输入保护。

汇编语言实现两个多位十进制数相减实验相关推荐

  1. 微型计算机原理实验报告总结,微机原理实验报告-两个多位十进制数相加的实验等.doc...

    微机原理实验报告-两个多位十进制数相加的实验等.doc 微机原理实验报告班级学号姓名实验一两个多位十进制数相加的实验一.实验目的学习数据传送和算术运算指令的用法熟悉在PC机上建立.汇编.链接.调试和运 ...

  2. 汇编实验1 两个多位十进制数相加的实验

    两个多位十进制数相加的实验 将两个多位十进制数相加,要求被加数和加数均以ASCII码形式各自顺序存放在以DATA1和DATA2为首的5个内存单元中(低位在前),结果送回DATA1处. ;定义宏实现回车 ...

  3. 汇编语言--键盘输入两个一位十进制数 ,以十进制数的形式输出其和

    键盘输入两个一位十进制数 ,以十进制数的形式输出其和 stack segment db 10 dup(?) stack endsdata segment ;显示提示语句 string_1 db 'in ...

  4. 51单片机实现三位十进制数加减乘除运算

    51单片机实现三位十进制数加减乘除运算 一.题目 51单片机IO接口作业 请将附件给出的Proteus图用51单片机完成一个计算器功能. 1.显示采用动态分时8位共阳数码管输出. 2.采用4*4矩阵键 ...

  5. “数学黑洞”:任意一个4位自然数,将组成该数的各位数字重新排列,形成一个最大数和一个最小数,之后两数相减,其差仍为一个自然数。重复进行上述运算,最终会出现一个神秘的数,请编程输出这个神秘的数。

    "数学黑洞":任意一个各位不相等的4位自然数,将组成该数的各位数字重新排列,形成一个最大数和一个最小数,之后两数相减,其差仍为一个自然数.重复进行上述运算,最终会出现一个神秘的数, ...

  6. C语言 请使用short int型的变量计算两个7位十进制整数的和,要求使用尽可能少的变量

    请使用short int型的变量计算两个7位十进制整数的和,要求使用尽可能少的变量. (提示:需要输入四个数,分别是第一个数的前三位和后四位,第二个数的前三位和后四位.分别求和,注意后四位产生的进位. ...

  7. C语言练习题,short int型的变量计算两个7位十进制整数的和

    请使用short int型的变量计算两个7位十进制整数的和,要求使用尽可能少的变量. **输入格式要求:"a = %3hd%4hd, b = %3hd%4hd" **输出格式要求: ...

  8. 2021数字电路课程设计 一位十进制数加减法运算电路

    设计任务: 用集成芯片设计一位十进制数加减法运算电路,具体要求如下: (1)能实现一位十进制数的加法运算,最大值为9+9=18. (2)能实现一位十进制数的减法运算,最小值为0-9=-9. (3)能显 ...

  9. 计算方法--编程计算当x很小,接近零时计算(1-cos(x))/sin(x)的值,怎么样避免这种两个相近的数相减产生误差。

    由于两个正数的差u=x-y的相对误差是:d(lnu)=(dx-dy)/(x-y),如果x和y很相近,它们的差就会很小,因而u的相对误差很大,这是由于x*和y*的前几位有效数字必然相同,相减以后有效数字 ...

最新文章

  1. 软件版权的双重许可是什么
  2. ArcGIS API For JS之网络分析(临近设施分析)
  3. 一文看懂哈夫曼树与哈夫曼编码
  4. Java Vistor 设计模式
  5. python discover()没有加载测试用例_Python系统学习 - Unittest
  6. 土豪也不会告诉你的IBM X3850 X5
  7. 苹果linux内核,意外!2020 年的 Linux 内核仍为苹果 Macintosh II 修复驱动
  8. 十大经典的心理学效应
  9. 搜索引擎技术优化原理及方法
  10. 【NOIP2016】魔法阵(节选自冬雪_狂舞_桀骜-xmy的博客)
  11. 共享店铺模式是怎么样的一个模式? 共享店铺系统多少钱一套?
  12. codeforces869EThe Untended Antiquity(二维树状数组)
  13. 倍福PLC获取伺服驱动器扭矩值获取电流值
  14. 博弈论(Game Theory)
  15. 机器学习算法(一): 基于逻辑回归的分类预测③
  16. Unity骚操作:Spine动画打包成AssetBundle资源到安卓平台时,材质丢失的问题解决方案
  17. ubuntu 安装五笔拼音输入法
  18. ansys时间步长怎么设置_在 ANSYS Workbench 的动态、静态仿真中,设置子步长(时间步长)的目的分别是什么?_学小易找答案...
  19. 阿里巴巴2008年创纪录狂招2000多销售人才
  20. 怎样用photoshop制作表情包?

热门文章

  1. n平方的求和公式_n的二次方怎么求和?
  2. python遥感影像分类代码_【博客翻译】使用 Python Tensorflow 实现简单的神经网络卫星遥感影像分类...
  3. Android Studio问题解决:Gradle sync failed: Sync failed: reason unknown
  4. 美国本科计算机专业叫cs吗,美国本科cs专业
  5. 在20岁到30岁的约定
  6. navicat for mysql 10.1.7注册码
  7. 浅谈微信小程序的功能定位和使用场景
  8. 雄岸基金战略投资 Filenet,共建分布式存储新生态
  9. 五一去哪里人最多?用 Python 抓取的热力图告诉你!
  10. pdf口令安全性破解