This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Why doesn't the NOAREGS works?

#pragma NOAREGS
char noaregfunc(char i) using 1
{
    return i+1;
}
void main(void)
{
    char ch = noaregfunc(2);
}
Source code:
                 C_STARTUP:
C:0x0000    020011   LJMP     C:0011
     2: char noaregfunc (char i) using 1 
     3: { 
C:0x0003    C0D0     PUSH     PSW(0xD0)
C:0x0005    75D008   MOV      PSW(0xD0),#0x08
C:0x0008    8F10     MOV      0x10,R7
     4:         return i+1; 
C:0x000A    E510     MOV      A,0x10
C:0x000C    04       INC      A
C:0x000D    FF       MOV      R7,A
     5: } 
     6:  
C:0x000E    D0D0     POP      PSW(0xD0)
C:0x0010    22       RET      
C:0x0011    787F     MOV      R0,#0x7F
C:0x0013    E4       CLR      A
C:0x0014    F6       MOV      @R0,A
C:0x0015    D8FD     DJNZ     R0,C:0014
C:0x0017    758111   MOV      SP(0x81),#0x11
C:0x001A    02001D   LJMP     main(C:001D)
     7: void main(void) 
     8: { 
     9:         char ch = noaregfunc(2); 
C:0x001D    7F02     MOV      R7,#0x02
C:0x001F    120003   LCALL    noaregfunc(C:0003)
C:0x0022    8F11     MOV      0x11,R7
    10: } 
C:0x0024    22       RET      
I can't get the right answer after calling noaregfunc.why?#pragma NOAREGS doesn't works?

  • I can't get the right answer after calling noaregfunc.why?#pragma NOAREGS doesn't works?

    This program works EXACTLY as it was programmed to work. main uses register bank 0 and noaregfunc uses registers in register bank 1.

    The reason you don't get the results you expect is because the return value from noaregfunc is stored in R7 (in register bank 1). Since the main function uses register bank 0, that's where it looks for the return value (in R7). And surprise, surprise. The correct value isn't there. It's in register bank 1!

    I'm not sure I understand what you are trying to accomplish with this program. There is no good reason to use register banks the way you do in this example. Register banks are really designed to be used with interrupt service routines to save time and so that the ISR doesn't have to push and pop all 8 registers. But, selecting a new register bank is not required. In fact, most 8051 programs only use register bank 0.

    You may want to take a careful look at the 8051 data sheet and focus your attention on the architecture section.

    Jon

  • Dear Mike,
    May I know why at beggining of code there is a jump to 0x011 in code space where

    C:0x0011 787F MOV R0,#0x7F
    C:0x0013 E4 CLR A
    C:0x0014 F6 MOV @R0,A
    C:0x0015 D8FD DJNZ R0,C:0014
    C:0x0017 758111 MOV SP(0x81),#0x11
    C:0x001A 02001D LJMP main(C:001D)

    it sets 0x7F of data space to 00h, then sets SP before returning. Isn't 7Fh just below the SFRs? Why does keil need to set this to 00h?

    Regards,
    KC

  • May I know why at beggining of code there is a jump to 0x011 in code space where

    This is the startup code. If you look at it carefully, you'll see that it clears the contents of DATA memory to 0. In the C programming language, all global variables which are not specifically initialized have a value of 0.

    Jon