首先发发牢骚吧(并未企图破坏论坛内人员团结,也非煽动);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
以下补充算法分析:
- 标 题:再议汇编判断闰年(16位实模式)
- 作 者:hjzco
- 时 间:2010-06-24 16:18:42
- 链 接:http://bbs.pediy.com/showthread.php?t=115655