| 汇编语言的艺术(组合语言的艺术)--基本认识(2) |
| 责任编辑:admin 更新日期:2005-8-6 |
nbsp;, 71 秒
CL = 6 , 49 秒 n = 6 , 85 秒
CL = 7 , 54 秒 n = 7 , 99 秒
由此可知,用CL在大于2时即较分别执行有效。
此外,亦可利用回路做加减法,但要算算值不值得,且应注意是否有调整余数的需要。
10, MOV WORD PTR BUF1,0
MOV WORD PTR BUF2,0
MOV WORD PTR BUF3,0
MOV BYTE PTR BUF4,0
..
我见过太多这种程式,一见就无名火起! 在程式中,最好经常保留一个暂存器为0,以便应付这种情况。即使没有,也要设法使一暂存器为0,以节省时、空。
SUB AX,AX
MOV BUF1,AX
MOV BUF2,AX
MOV BUF3,AX
MOV BUF4,AL
14B,59T取代了 24B,76T,当然值得。只是,还是不 如事先有组织,考虑清楚各个缓冲器间的应用关系。以前面举的例来说,假定各缓冲器内数字,即为其实际位置关系,则可以写成:
MOV CX,3
如已知 CH 为0,则用:
MOV CL,3
SUB AX,AX
MOV DI,OFFSET BUF1
REP STOSW
STOSB
这段程式越长越占便宜,现在用10B,37T,一样划算。
11,子程式之连续调用:
CALL ABCD
CALL EFGH
如果 ABCD,EFGH 都是子程式,且调用的次数甚多,则上述调用的方式就有待商榷了。因为连续两次调用,不仅时间上不划算,空间也浪费。
若ABCD一定与EFGH连用,应将ABCD放在EFGH之前:
ABCD:
..
EFGH:
..
像这样,只要调用ABCD就够了,但这种情形多半是程式师的疏忽所致,如两个子程式必需独立使用,而上述连续调用的机会超过两次以上,则应该改为:
CALL ABCDEF
而ABCDEF则应为:
ABCDEF:
CALL ABCD
EFGH:
..
这样的写法速度不会变慢,而空间的节省则与调用的次数成正比。
12,常有些程式,当从缓冲器中取资料时,必须将暂存器高位置为0。如:
SUB AH,AH
MOV AL,BUFFER
这时应该将 BUFFER 先设为:
BUFFER DB ?,0
然后用:
MOV AX,WORD PTR BUFFER
如此,不但速度快了,空间也省了。
13,有时看来多了一个指令,但因为指令的特性,反而更为精简。如:
OR ES:[DI],BH
OR ES:[DI+1],BL
这样需要8B,32T,如果改用下面的指令:
XCHG BL,BH
OR ES:[DI],BX
XCHG BH,BL
则需7B,28T。
14,PUSH 及 POP 是保存暂存器原值的指令,都只需一个字元,但却很费时间。
PUSH 占 15T,POP 占12T,除非不得已,不可随便使用。有时由于子程式说明不清楚,程式师为了安全,又懒得检查,便把暂存器统统堆在堆栈上。尤其是在系统程式或子程式中,经常有到堆栈上堆、取的动作。实际上,花点功夫,把暂存器应用查清楚,就可以增进不少效率。
要知道,系统程式及某些子程式常常应用,有关速度的效率甚大,如果掉以轻心,就是不负责任!
保存原值的方法很多,其中较有效率的是放到一些不用的暂存器里。以我的经验,堆栈器用途最少,正好用作临时仓库。但最好的办法,还是把程式中暂存器的应用安排得合情合理,不要浪费,以免堆得太多。
还有一种方法,是在该子程式中,不用堆栈的手续,但另设一个入口,先将暂存器堆起,再来调用不用堆栈的子程式。这两个不同的入口,可以分别提供给希望快速处理,或需要保留暂存器原值者调用。
当然,更简单有效的方法,则是说明本段程式中某些暂存器将被破坏,而由调用者自行保存之。 |
|