l4m2 发表于 2014-7-3 11:21:12

有搞单片机的吗

都说单片机最好不重入。可是
      ORG 0000H
   LJMP 0030H
      ORG 002FH
   RETI
START:MOV SP,#127
      MOV R2,#10
    ACALL ADDTO
      MOV P1,A
   SJMP $
ADDTO:MOV A,R2
       JZ ZERO
   PUSH ACC
      DEC R2
    ACALL ADDTO
      POP B
      MOV R2,B
      ADD A,B
      RET
ZERO: CLR A
      RET
          END
对应C中
char addto(char i){
return i?addto(i-1)+i:0;
}
void main(){
P1=addto(10);
}
不见得花多少时间(82us,164周期)
在大工程中更不觉有什么不同
为什么呢

cn8888 发表于 2014-7-3 16:23:07

完全不懂单片机,但是听说过VHDL

风云剑 发表于 2014-7-3 21:39:34

并不是说不能重入。而是因为早期的单片机RAM资源太少,递归深了很快资源耗尽。

wayne 发表于 2014-7-3 22:21:20

多用寄存器,少用栈,对吧。

不过,现在的C/C++的函数 都是基于栈这个概念的。

wayne 发表于 2014-7-3 22:47:52

#include <stdio.h>

int addto(int i){
return i>0?addto(i-1)+i:0;
}

void addto2(int i,int *ans){
*ans = i>0?addto(i-1)+i:0;
}

int main(){

int n=0,PI=addto(10);
addto2(10,&n);
printf("PI=%d\tn=%d",PI,n);
       
return 0;
}

l4m2 发表于 2014-7-3 23:14:37

Build target 'Target 1'
compiling main.c...
MAIN.C(3): warning C265: '_addto': recursive call to non-reentrant function
linking...
Program Size: data=10.0 xdata=0 code=43
"a" - 0 Error(s), 1 Warning(s).

用reentrant则
193.5us ~ 324.0us = 130.5
C:0x0000    02001F   LJMP   C:001F
   2:   char addto(char i)reentrant {
C:0x0003    1508   DEC      ?C_IBP(0x08)
C:0x0005    A808   MOV      R0,?C_IBP(0x08)
C:0x0007    A607   MOV      @R0,0x07
   3:       return i?addto(i-1)+i:0;
C:0x0009    A808   MOV      R0,?C_IBP(0x08)
C:0x000B    E6       MOV      A,@R0
C:0x000C    600C   JZ       C:001A
C:0x000E    14       DEC      A
C:0x000F    FF       MOV      R7,A
C:0x0010    120003   LCALL    addto(C:0003)
C:0x0013    A808   MOV      R0,?C_IBP(0x08)
C:0x0015    E6       MOV      A,@R0
C:0x0016    2F       ADD      A,R7
C:0x0017    FF       MOV      R7,A
C:0x0018    8002   SJMP   C:001C
C:0x001A    7F00   MOV      R7,#0x00
   4:   }
C:0x001C    0508   INC      ?C_IBP(0x08)
C:0x001E    22       RET      
C:0x001F    787F   MOV      R0,#0x7F
C:0x0021    E4       CLR      A
C:0x0022    F6       MOV      @R0,A
C:0x0023    D8FD   DJNZ   R0,C:0022
C:0x0025    758108   MOV      SP(0x81),#?C_IBP(0x08)
C:0x0028    02002B   LJMP   main(C:002B)
   5:   void main(){
   6:       P1=addto(10);
C:0x002B    7F0A   MOV      R7,#0x0A
C:0x002D    120003   LCALL    addto(C:0003)
C:0x0030    8F90   MOV      P1(0x90),R7
   7:   }
C:0x0032    22       RET      
页: [1]
查看完整版本: 有搞单片机的吗