汇编程序的优化问题

  用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),指令条数掐指可数。这保证了它的运行速度远远优于第一个程序。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值