WEB开发网
开发学院软件开发汇编语言 汇编语言的艺术-基本认识(三) 阅读

汇编语言的艺术-基本认识(三)

 2007-04-25 09:30:08 来源:WEB开发网   
核心提示:23: CHANGS: 24: CMP AL,41H 25: JB CHARET 26: CMP AL,5AH 27: JA CHARET 28: CLC 29: RET 这种程式错在把由12到29的程式写得太长,共 25B,汇编语言的艺术-基本认识(三)(2),有共用的价值,于是作为子程式调用,是绝对得不偿失的, 再

23: CHANGS:
24: CMP AL,41H
25: JB CHARET
26: CMP AL,5AH
27: JA CHARET
28: CLC
29: RET
这种程式错在把由12到29的程式写得太长,共 25B,有共用的价值,于是作为子程式调用。

试想一下,每一笔资料,都要调用一次,浪费四个字元事小,但每次要费 23+20个时钟脉冲,资料多时,不啻为天文数字。更何况这段程式写得极差,在回路中,又多浪费了几十个时钟。关于这一点,下面会继续讨论。
照上面这段程式,略加改进,写法如下:
1: CHANGE:
2: LODSB
3: OR BL,BL
4: JZ CHANGS
5: CMP AL,61H
6: JB CHARET
7: CMP AL,7AH
8: JA CHARET
9: SUB AL,20H
10: CHANG0:
11: MOV [SI-1],AL
12: CHANG1:
13: LOOP CHANGE
14: RET
15: CHANGS:
16: CMP AL,41H
17: JB CHANG1
18: CMP AL,5AH
19: JA CHANG1
20: ADD AL,20H
21: JMP CHANG1
这样的写法还是不佳,因为在回路中,用常数与暂存器比较,速度较暂存器相比为慢。应该先将需要比较的值,放在暂存器DH,DL 中,改进如次:
1: MOV AH,20H
2: MOV DX,7A61H
3: OR BL,BL
4: JZ CHANGE
5: MOV DX,5A41H
6: CHANGE:
7: LODSB
8: CMP AL,DL
9: JB CHANG1
10: CMP AL,DH
11: JA CHANG1
12: XOR AL,AH
13: MOV [SI-1],AL
14: CHANG1:
15: LOOP CHANGE
16: RET
以上这段程式,空间小,速度快,每笔资料,平均仅需不到40个时钟值,以10 MHZ计,十万笔资料,约需半秒钟!
请注意程式中所用的技巧,由2至6的分支法,就比下面这种写法为佳:
1: OR BL,BL
2: JZ CHAN1 
3: MOV DX,5A41H
4: JMP SHORT CHANGE
5: CHAN1:
6: MOV DX,7A61H
7: CHANGE:
这种分支也可以由另一种技巧所取代,即预设法。事先将所需用的参数放在固定的缓冲区中,此时取用即可:
MOV DX,BWCOM ; 比较之预设值 
这样程式又简单些了:
1: MOV AH,20H
2: MOV DX,BWCOM
3: CHANGE:
4: LODSB
5: CMP AL,DL
6: JB CHANG1
7: CMP AL,DH
8: JA CHANG1
9: XOR AL,AH
10: MOV [SI-1],AL
11: CHANG1:
12: LOOP CHANGE
13: RET

以上介绍为变数法技巧,即将所要比较的值,放在暂存器中。由于暂存器快速、节省空间,因此程式效率高。更重要的一点,是程式本身的弹性大,只要应用方式统一,事先把参数设妥,即可共用。

四、回路中的指令

回路最重要的是速度,因为本段程式,将在计数器的范围之内,连续执行下去。如果不小心浪费了几个时钟值,在回路的累积下,很可能使程式成为牛步。
要想把回路写好,一定要记清楚每个指令的执行时钟,以便选择效率最高者。同时,要知道哪些指令可以获得相同的处理效果,才能有更多的选择。
其次,在回路中,最忌讳用缓冲器,不仅占用空间大,处理速度慢,而且不能灵活运用,功能有限。另外也应极力避免常数,尽量设法经由暂存器执行,用得巧妙时,常会将整个程式的效率提高百十倍。
还有便是少用 PUSH,POP,DIV,MUL和 CALL 等浪费时钟的指令。除此之外,小心、谨慎,深思、熟虑,才是把回路写好的不二法门。
在前例中,把比较常数的指令换为比较暂存器,便是很好的证明。如果用常数,两段程式决不可能共用,时、空都无谓地浪费了。
以下再举数例,乍看这似乎有些吹毛求疵,但是仔细计算一下所浪费的时间,可能就笑不出声了。
兹假定以下回路需处理五万字元的资料,频率为 10MHZ,其情况为:
1: LOOP1:
2: LODSB
3: XOR AL,[DI]
4: STOSB
5: LOOP LOOP1
本程式计数器等于50,000,每次需
12T+14T+11T+17T=55T 个时钟脉冲
若以50,000次计,需时 47*50,000/10,000,000 秒,即约四分之一秒。
只要稍稍将指令调整一下,为:
1: LOOP1:
2: LODSW
3: XOR AX,[DI]
4: STOSW
5: LOOP LOOP1
这样计数器只要25,000次,每次
16T+18T+15T+17T=66T
则25,000次需时 66*25,000/10,000,000 秒,约六分之一秒,比前面的程式快了二分之一。
同理,在回路中加回路,而每个回路需 17T,也是很大的浪费。倘若加调用 CALL 指令,则需 23T+20T=43T,浪费得更多,读者不可不慎。
当某一段程式用得很频繁时,理应视作子程式,例如下面的 LODAX:
1: LOOP1:
2: CALL LODAX
3: LOOP LOOP1
4: RET
5: LODAX:
6: LODSW
7: XOR AX,[DI]
8: STOSW
9: RET
其实这是贪小失大,仅四个字元的程式,竟用三个字元的调用指令去交换,是绝对得不偿失的。
再如同下面的程式,颇有值得商榷之处。
1: LOOP1:
2: MOV DX,NUMBER1
3: MOV CX,NUMBER2
4: LOOP2:
5: PUSH CX
6: MOV CX,DX
7: LOOP3:
8: LODSW
9: XOR AX,[DI]

上一页  1 2 3 4  下一页

Tags:汇编语言 艺术 基本

编辑录入:爽爽 [复制链接] [打 印]
赞助商链接