用C++等高级语言写程序,主要的优化问题是算法效率问题。因此,并不需要对写了多少条语句苛求太多,甚至为了阅读的方便,我们还会特意把诸如这条语句:
int a,b; //注释……
分成两条来写:
int a; //注释a……
int b; //注释a……
这样分开来写的一个优点,就是为了方便分别注释,使阅读更舒服。
事实上,我们能够这样去增加语句,得益于编译器。因为一个良好的编译器,能够把这两种写作方式的语句,翻译成同样的机器码。
可是,如果我们是在在单片上写汇编程,那么就不能尽情去发挥我们的写作才华了^_^。因为单片机中(我所学的是MS-51系列),每一条汇编指令的所花的机器周期都已经确定。所以,实现同一个功能的程序,也许有些人用了100条指令,而有些人只用了50条。这两个的程序的效率是不言而喻的。
以下,是自己两次实现同一个冒泡排序的汇编程序,大家看一看之后就会发现,用汇编写程序时,不能再为了阅读的方便而不惜浪费指令数,否则,效率的差异是惊人的!
;;;;;;;;;;;冒泡排序,追算法上的直观;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
mov R0, #0 ;R0=>i for(i=0; i<10; i++)
loop1: mov R1, R0 ;R1=>j for(j=i+1; j<10; j++)
inc R1
mov DPTR, #1000H ;get the value[i] and save it to R3
mov A, R0
movc A, @A+DPTR
mov R3, A
loop2: mov A, R1 ;get the value[j] and save it to R4
movc A, @A+DPTR
mov R4, A
clr c ;compare the value[i] and value[j],if value[i]<value[j],swap them
subb A, R3
jc entry1
mov A, R1 ;swap value[i] and vlaue[j]
add A, DPL
mov DPL, A
mov A, R3 ;value[i]
movx @DPTR, A ;value[j] <= R3
mov A, R0
add A, DPL
mov DPL, A
mov A, R4 ;value[j]
movx @DPTR, A ;value[i] <= R4, swap completely!
entry1: inc R1
cjne R1, #10, loop2; currect?maby false
inc R0
cjne R0, #10, loop1
;;;;;;;;;;;;;;;;;;pass the 10 value ;;;;;;;;;;;;;;;;;;;;;;;;;;;;
mov R7, #10 ;used to control loop
mov R0, #0 ;used to control outside ram's address
loop1: mov DPTR, #1000H ;read the orginal value
mov A, R0
movc A, @A+DPTR
mov R3, A ;save the value tempemtly in R3
mov R1, #21H ;set distinct address
mov A, R1
add A, R0
mov R1, A
mov A, R3 ;pass the value to distinct address
movx @R1, A
inc R0
djnz R7, loop1 ;if (R7)-1 != 0 then goto the loop1
;;;;;;;;;;;;;;;;;;;;;;;;;冒泡法,珍惜指令数;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;采用冒泡法排序
;for(i=0+k; i<N+k; i++) k=30H为首地址,N=10为循环次数 R0为i
mov R0, #30H ;Intitial R0
;for(j=N+K-1; j>i; j--) R1为j
lp1: mov R1, #39H ;Intitial R1
lp2: mov A, @R1 ;compare @R1 and @R0
subb A, @R0 ;if @R1 > @R0 ,xch them
jc uxch
mov A, @R1 ;xch (R1) and (R0)
xch A, @R0
xch A, @R1
uxch: dec R1 ;j--
mov A, R0
subb A, R1
jc lp2 ;j>i then goto lp2
inc R0 ;i++
cjne R0, #3AH, lp1 ;i<N+k
end
一眼就可以看出,第二个程序是令人喜欢的。尽管它的循环不是从0开始计数,但它只使用了三个寄存器(R0,R1,A),指令条数掐指可数。这保证了它的运行速度远远优于第一个程序。