Topic : Compiler generates weird code again

Forum : ST7/STM8

Original Post
Post Information Post
May 20, 2011 - 12:53pm
Guest

I have a few lines of code that crashes. When I start to analyze the cause of the crash it seems like the compiler generates code that actually crashes. Please take a look at the example below and see what you think.

I have a function called func2, the first thing that happens when we enter the function is that a number of bytes is reserved on the stack for local variables. In this case, it looks like this

; FUNCTION ?func2 (BEGIN)
; Register-parameter s (XW) is relocated (auto)
; SOURCE LINE # 49
0000 89 PUSHW X
0001 5203 SUB SP,#003H

Here we can see that three bytes are reserved on the stack. This is fine, however , but if we look at these lines futher down in the function.

001C A602 LD A,#002H
001E ?OPTI_0001:
001E 6B07 F LD (007H,SP),A ; [ speed ]

we can see that the value in register A is inserted into the stack variable (speed) at offset 7 !! This is outside the reserved range for local variables. So what happens is that the return address is overwritten and when we return from func2() ( executing RET) we jump into void! This is bad.

This error only happen when I use the maximum level of optimization(7) and optimize for size.

The complete source code that can be used to reproduce the error.

#include

typedef unsigned char uint8_t;
typedef unsigned long uint32_t;
typedef unsigned short uint16_t;

typedef enum
{
ITEM1,
ITEM2,
ITEM3,
ITEM4
} EnumType;

typedef enum
{
SPEED1,
SPEED2,
SPEED3,
SPEED4
} Speed;

char buf[200];
static int count = 0;
int putchar(char c)
{
buf[count++] = c;
return 1;
}

void error(char *p1, uint32_t p2)
{
printf("%s %d", p1, (int)p2);
}

int func1(EnumType p1, EnumType p2, EnumType p3, uint8_t s)
{
volatile uint16_t r1, r2, r3, r4;

r1 = p1;
r2 = p2;
r3 = p3;
r4 = s;
return 0;
}

int func2(Speed s)
{
int ret = 0;
uint8_t speed;

EnumType p1;
EnumType p2;
EnumType p3;

p1 = ITEM4;
p2 = ITEM2;
p3 = ITEM1;

switch (s)
{
case SPEED1:
speed = 2;
break;
case SPEED2:
speed = 3;
break;
case SPEED3:
speed = 4;
break;
case SPEED4:
break;
default:
error(__FILE__, __LINE__);
}
ret = func1(p1, p2, p3, speed);
return ret;
}

void main(void)
{
volatile Speed s = SPEED2;
int f;
f = func2(s);

// The next line will never be executed because the program crashes when returning from func2()
printf("%d\n", f);
}

This is the output for function func2() the the main.lst file

; FUNCTION ?func2 (BEGIN)
; Register-parameter s (XW) is relocated (auto)
; SOURCE LINE # 49
0000 89 PUSHW X
0001 5203 SUB SP,#003H
; SOURCE LINE # 62
0003 1E04 F LDW X,(004H,SP) ; [ s ]
0005 2715 JREQ ?CASE_0004
0007 5A DECW X
0008 2718 JREQ ?CASE_0005
000A 5A DECW X
000B 2719 JREQ ?CASE_0006
000D 5A DECW X
000E 271C JREQ ?NXT_0001
0010 CD0000 F DNF M(04) CALL ?C?mv4_pg2sk1
0013 ?DATASTART_0001:
0013 4C M DB 04CH
0014 ?DATAEND_0001:
0014 AE0000 F LDW X,#HIGH(?STR?MAIN?BASE + 006H)
0017 CD0000 F CALL ?error
001A 200E JRA ?DEFAULT_0001
001C ?CASE_0004:
; SOURCE LINE # 65
001C A602 LD A,#002H
001E ?OPTI_0001:
001E 6B07 F LD (007H,SP),A ; [ speed ]
; SOURCE LINE # 66
0020 200A JRA ?NXT_0001
0022 ?CASE_0005:
; SOURCE LINE # 68
0022 A603 LD A,#003H
; SOURCE LINE # 69
0024 20F8 JRA ?OPTI_0001
0026 ?CASE_0006:
; SOURCE LINE # 71
0026 A604 LD A,#004H
; SOURCE LINE # 72
0028 20F4 JRA ?OPTI_0001
002A ?DEFAULT_0001:
; SOURCE LINE # 76
002A 5B04 ADD SP,#004H
002C ?NXT_0001:
; SOURCE LINE # 78
002C 7B03 F LD A,(003H,SP) ; [ speed ]
002E 88 PUSH A
002F 5F CLRW X
0030 89 PUSHW X
0031 5C INCW X
0032 89 PUSHW X
0033 AE0003 LDW X,#00003H
0036 CD0000 F CALL ?func1
0039 5B0A ADD SP,#00AH
; SOURCE LINE # 79
003B 81 RET

Then I compiled the file I used the Ride7 IDE and the compilation line looks like this

"C:\Program Files (x86)\Raisonance\Ride\Bin\RCSTM8.EXE" "C:\src\testr\main.c" QUIET GENERATEDEPFILE CODE DB OJ("C:\src\testr\main.obj") PR("C:\src\testr\main.lst") PIN("C:\Program Files (x86)\Raisonance\Ride\Inc;C:\Program Files (x86)\Raisonance\Ride\Inc\ST7") STM8(SMALL) DGC(DATA) O(3,SIZE) INITSTATICVAR ET(INT) LISTINCLUDE
My tools:
STM8 compiler/linker ver 2.32.10.0307
I am compiling for the STM8 family, SCINAME(STM8). Target CPU is STM8S207M8.

Best Regards
Andreas Hansson

Replies
Post Information Post
+1
0
-1
May 20, 2011 - 6:42pm
Raisonance Support Team

Hi Andreas,

Thanks for your report.
We have been able to reproduce the bug in our labs and fixed it.

The fix will be available in the next RKit-STM8 release, which is nearly out (well... I guess so :/)

Best Regards