欢迎来到 嗅灵易学

零基础也能上手的脚本技术课,一对一答疑带你入门

再议汇编判断闰年(16位实模式)

再议汇编判断闰年(16位实模式)

首先发发牢骚吧(并未企图破坏论坛内人员团结,也非煽动);2010年初开始自学汇编语言(16位),如果单就书本上的代码练习练习倒是没有什么问题,但是想学好编程不可能只是对照着书本来吧。所以就在网络上搜了一些练习的代码,而后找到<25个经典汇编程序>应该算是目前比较全的汇编练习代码集吧。
  当然迫不及待的打开,迫不及待的去试验试验自己的那点水平能否看懂里面的代码。结果呢,真的很令人失望,能看懂的还真少。于是就下决心去专研,当然肯遇到困难了但是经过一段时间后当我对汇编熟悉有一定了解,我发现了几个让我痛心疾首的问题:
  1.写代码的人相当的不负责任,可能连调试阶段都没有经过只要程序能够运行不管结果对与错就认为完成了工作。他们的目的是看见有 .exe 就认为对了,也不管能不能达到任务的需求。
  2.百度中的代码基本上是一大抄,人家错哪他们也错哪。好像对自己的学习处于应付的状态,提问的人想不明白、回答的人说不明白。一个个就在应付,我很想知道这是应付谁呢?有问题上百度这应该是现代人一个比较普遍的现象,可是现在百度能解决问题的又有多少?
  3.基本上没有注释,没有任何说明。对于初学者来说,去看别人的代码本来就是件不容易的事情;更何况去分析和理解最终掌握。写代码的人为什么不想想,你的代码思路清晰能帮助多少个所谓的"菜鸟"们成长。为什么国内的编程水平这么差,很大一部分原因就在于人们的态度。对待学术问题丝毫不严谨,对待自己的学业是应付。
  4.毫无格式可言。在<25个经典汇编程序>代码集中大部分代码都是"混乱分布",写代码的人大多数连空格都不舍得放那更别说空行了。代码全都挤在一起,就好像是一堆杂乱的毛线无从捋顺。
  个人建议,请写代码的前辈们真的要负责一点。中国人的责任心是在国际上都收抨击的,我们不应该引以为豪。请想学习的朋友们对自己认真负责一点,如果每个人都用心去对那些不负责任的前辈们的代码仔细阅读就会发现很多问题。当你发现了问题你就应该告诉我们的学弟学妹们,不让他们在为这"天书"一般的代码去发愁。我们的代码都应该有足够的注释,无论多简单。我们的代码要足够清晰即使是不会编程的人也能看出个所以然。试想下,如果前辈们可以做到这样那可以缩短后来人都少在菜鸟阶段的时间;如果前辈们都认真对待自己的程序,网络上又怎么可能出现那么多人云亦云的现象。请让你的代码清晰一点点,这花不了你多少时间。你的代码你日后能很快的温习过来,也可以造福后来人他们阅读你的代码。。。。
  确实罗嗦了一点,但是这却积压在我心中很久的郁闷。原本打算把<25个经典汇编程序>代码集中所有代码都改最清晰的方式在重新发出来,可是越改我就越难受越难受我就越想说;最后我就一吐心中不快,全部的说出来。
  希望我修改的代码能对和我一样在初学阶段的朋友们一点点提示,缩短"菜鸟"阶段的时间。
  以下是判断闰年的汇编代码(16位)
;程序名称:判断闰年
;功    能:判断闰年
assume     cs:code, ds:data, ss:stack_
data       segment
       Print_mess     db 0dh, 0ah,   'Please input a year: $'
       Resault_1      db 0dh, 0ah,   'This is a leap year! $'
       Resault_2      db 0dh, 0ah,   'This is not a leap year! $' 
       
       Write          dw   0
       ;用于保存转换后的输入数据的值(年份),年份的输入时ASCII形式的,必须将其转换为16进制形式的
       ;才能予以正常处理
       
       Buf            db   5
                      db   ?
                      db   5 dup (?)
       ;整个BUF功能和21h号中断功能0ah是对应的 
data       ends
stack_     segment   stack
       db  200 dup (0)
stack_     ends
code       segment
start:
       mov       ax,     data
       mov       ds,     ax
       ;
       lea       dx,     Print_mess
       mov       ah,     9
       int       21h
       ;作用是将提示信息显示出来 
       ;
       lea       dx,     Buf
       mov       ah,     0ah
       int       21h
       ;作用是等待用户输入的数据以便可进行判断 类似C语言的scanf
       ;
       mov       cl,     Buf + 1
       xor       ch,     ch
       ;Buf+1是实际输入数据的个数的地址,然后将该值赋予 CL 
       ;必须清 ch 因为在程序开始时cx中记录了该程序使用的字节数而ch中很可能有数据
       ;该数据可能会影响后面的操作,或者调试时候的判断  
       ;强调:在原著中没有 xor       ch,     ch  此句,如果调试是绝对看不见正确结果的 
       call      Asc_to_Hex
       call      Judge_
       ;Judge 判断 
       jc        Print_Resault
       
       ;不是闰年 
       lea       dx,     Resault_2
       mov       ah,     9
       int       21h
       jmp       EXIT
       ;是闰年       
Print_Resault:
       lea       dx,     Resault_1
       mov       ah,     9
       int       21h
       
EXIT:
       mov       ah,     4ch
       int       21h
       
;***********************************************************************************************       
;子程序名:Asc_to_Hex
;功    能:将以ASCII形式输入的数据转换成为16进制表示的数据
;入口参数:CX = Buf+1 实际输入数据的个数 
;出口参数:
Asc_to_Hex       PROC     NEAR
       push      cx
       dec       cx
       lea       si,     Buf + 2
       
Point_tail:
       inc       si
       loop      Point_tail
       pop       cx
       
       mov       dh,     30h
       mov       dl,     10
       mov       bx,     1
       mov       ax,     0
       ;
To_Asc:
       xor       ah,     ah
       ;sub       byte ptr [si],     dh 
       ;mov       al,     byte ptr [si]   警告: 破坏了原始数据 原著中存在 
       mov       al,     byte ptr [si]
       sub       al,     dh
       ; [si] 原本就指向一个字节数据 添加 byte ptr 作用是避免出错 起强调作用 也是个好的习惯 
       
       push      dx
       mul       bx
       pop       dx
       ;由于在乘除法运算过程中 DX AX 会被作为同一个寄存器来处理,故 DX 中的数据会被改变
       ;若不加数据保护 push pop 则 DX 中的数据会被清零,自然也达不到程序处理的要求
       ;原著中没有 push dx 和 pop dx 所以原著始终达不到正确结果 
       
       add       Write,   ax
       
       push      ax
       mov       ax,      bx
       mul       dl
       mov       bx,      ax
       pop       ax
       
       dec       si
       loop      To_Asc
       
       ret
Asc_to_Hex       ENDP
;***********************************************************************************************

;***********************************************************************************************
;程序名称:Judge_
;功    能:判断是否是闰年
;入口参数:Write
;出口参数:判断结果 
Judge_           PROC     NEAR
       push      bx
       push      cx
       push      dx
       
       mov       ax,      Write
       mov       cx,      ax
       ;对年份数据备份 
       mov       dx,      0
       mov       bx,      4
       div       bx
       cmp       dx,      0
       ;检查余数,通过检查余数可以得知该数数否能被整除 
       jnz       Judge_1
       
       mov       ax,      cx
       mov       bx,      100
       mov       dx,      0
       div       bx
       cmp       dx,      0
       jnz       Judge_2
       
       mov       ax,      cx
       mov       bx,      400
       mov       dx,      0
       div       bx
       cmp       dx,      0
       jz        Judge_2
Judge_1:
       clc
       ; Clear Carry Flag 清进位标志 CF=0表示不是闰年 
       jmp       Judge_3
       
Judge_2:
       stc
       ; Set Carry Flag   置进位标志 CF=1表示是闰年
       
Judge_3:
       pop       dx
       pop       cx
       pop       bx       
       ret
Judge_           ENDP
;***********************************************************************************************
code             ENDS
                 END     start  
以下补充算法分析:

注意:上传附件及图片大小不得大于30M。

⚠️ 版权声明:
本博客所有内容(含教程、源码、工具)仅供个人技术学习与研究交流使用,严禁商用、倒卖、二次分发及非法用途。
未经作者书面授权,任何组织或个人不得转载、复制或用于其他平台,违者将追究相关责任。

0 0 0 举报
复制成功