#920 mcs51 pushing/popping R0 corrupts stack


Saw this on a Cygnal 8051f300 (no external RAM).
main() used the reentrant keyword to get data to fit
below 0x80.

printf() accepts its arguments on the stack. If all
arguments exist in (or can be copied to) data
registers, no problem, they're pushed onto stack
directly without "helper" registers. If an argument
resides on current stack frame, it's pushed onto
argument list with the help of accumulator and R0. In
some situations, the compiler generates code to
save(push) R0 on the stack, push the argument onto the
stack via ACC and R0, and immediately restore(pop) R0,
both corrupting R0 and causing the printf argument list
to "slip" one byte of data.

void main (void) reentrant
signed short tempAdj=0;
signed char tempInt=0;
short prevxg = 0;
short prevyg = 0;
unsigned char tempFrac=0;
printf("%d.%dC N=%dmg ", tempInt, tempFrac, tempAdj);
; genCast
push ar0 ;here using ACC and R0 to int cast
mov a,_bp ; char tempFrac into R2 and R3
add a,#0x18
mov r0,a ;
mov ar2,@r0
mov r3,#0x00
pop ar0
; genCast
push ar0
mov a,_bp ;here using ACC and R0 to int cast
add a,#0x13
mov r0,a ; char tempInt to R4 and R5
mov ar4,@r0
mov a,@r0
rlc a
subb a,acc
mov r5,a
pop ar0

; genIpush
push ar0
push ar1
push ar0
mov a,_bp ; pushing tempAdj onto stack
add a,#0x11 ; with help of R0.
mov r0,a
mov a,@r0
push acc
inc r0
mov a,@r0
push acc
pop ar0 ; HERE! popping in middle of argument
; genIpush
push ar2 ; pushing tempFrac onto arglist
push ar3
; genIpush
push ar4 ; pushing tempInt onto arglist
push ar5
; genIpush
mov a,#__str_4 ;pushing char* format onto
push acc
mov a,#(__str_4 >> 8)
push acc
mov a,#0x02
push acc
; genCall
lcall _printf
mov a,sp ; sp is correctly restored to its
pre- printf
add a,#0xf7 ; value so program continues
mov sp,a
pop ar1
pop ar0


This problem first appeared when I started using code
pointers to RAM space in my code.
The strangest thing is when I added a printf on a code
pointer to RAM space (to look for stack overflow), the
problem went away.
// add to main auto var list
static data char* pStackTop = 0xff;

// add to bottom of loop
printf ("%2X", *pStackTop);

With this line added, the generated asm code doesn't
have all the R0 push/pop's.
Comment this line out, and they're all back again.


  • Maarten Brock

    Maarten Brock - 2005-05-12

    Logged In: YES

    You did not supply:
    * SDCC version
    * command-line options used
    * compilable source to reproduce the problem
    But I bet you used an old version and this should be solved
    already for some time now.

  • seedav99

    seedav99 - 2005-05-15

    Logged In: YES

    Please close this report. I encountered this problem in
    version 2.4.0.
    It no longer exists in v 2.4.6.

  • Maarten Brock

    Maarten Brock - 2005-05-15
    • milestone: --> fixed
    • status: open --> closed-out-of-date

Log in to post a comment.

Get latest updates about Open Source Projects, Conferences and News.

Sign up for the SourceForge newsletter:

No, thanks