EmbeddedRelated.com
Forums

IAR Compiler - Stack Auto vars mis-alignment

Started by Matthew Bivans August 1, 2002
I've run across a bug in the latest (1.26a) rev. of the IAR compiler
for the MSP430.  The compiler doesn't generate correct word addresses for
auto variables located on the stack when the variable is declared in a sub-scope
after code in a function.  It's not an easy set of circumstances to
explain, but if you compile the follow code in ew1.26a you'll see nVal end
up at offset 13 from the SP!.  The resulting assembly output is located below
for both 1.24 and 1.26.  If you run it in C-SPY you can see the misalignment
clearly.  It appears to be okay in ew1.24a.

After going back-and-forth with IAR for over a month on this I finally found out
that the first possible date for a fix is 2/2003.  So, I wanted to at least make
everyone here aware of this.

matt b.

Example Code:

#include <stdio.h>
void main(void)
{
    char pRcvData[11];

    {                
        char cChr = 0;
        sscanf(pRcvData,"%c",&cChr);
    }

    {
	  /* Here's where the trouble occurs, in ew1.26a nVal is located
        at 13 bytes offset from the SP!, which doesn't work because
        word accesses (even the initialization to 0x1234) can't be
        done to odd addresses.  EW1.24a handles this fine */
        
        unsigned int nVal = 0x1234;
        sscanf(pRcvData,"%u",&nVal);
    }    
}

Results using ew1.26A:
main:
	SUB	#16,SP	
	MOV.B	#0,12(SP)	
	MOV	SP,R12	
	ADD	#12,R12	
	PUSH	R12	
	PUSH	#?0010	
	MOV	SP,R12	
	ADD	#4,R12	
	CALL	#sscanf	
	ADD	#4,SP	
	MOV	#4660,13(SP)	<<< note the odd SP offset, 4660 is actaully written
to 12(SP)
	MOV	SP,R12	
	ADD	#13,R12	
	PUSH	R12	
	PUSH	#?0011	
	MOV	SP,R12	
	ADD	#4,R12	
	CALL	#sscanf	
	ADD	#4,SP	
	ADD	#16,SP	
	RET		
	RSEG	CSTR
?0010:
	DB	'%c'
	DB	0
?0011:
	DB	'%u'
	DB	0
	END

Results using ew1.24A:
main:
	SUB	#14,SP	
	MOV.B	#0,11(SP)	
	MOV	SP,R12	
	ADD	#11,R12	
	PUSH	R12	
	PUSH	#?0010	
	MOV	SP,R12	
	ADD	#4,R12	
	CALL	#sscanf	
	ADD	#4,SP	
	MOV	#4660,12(SP)   << even stack offset is okay	
	MOV	SP,R12	
	ADD	#12,R12	
	PUSH	R12	
	PUSH	#?0011	
	MOV	SP,R12	
	ADD	#4,R12	
	CALL	#sscanf	
	ADD	#4,SP	
	ADD	#14,SP	
	RET		
	RSEG	CSTR
?0010:
	DB	'%c'
	DB	0
?0011:
	DB	'%u'
	DB	0
	END



Beginning Microcontrollers with the MSP430

Well spotted Mathhew,
 
Have had problems with "odd" alignments for a long time too.
(Like in structs etc)
IAR always said "it was not a bug" (which actually many times it isn't, depending on runtime).
IAR promised to promptly implement a utility that checks for "odd" situations, but that doesn't work very well ?
Furthermore, simple things like writing a float with sscanf() into a char array in RAM gave problems too.
 
Fair enough, the compiler/linker simply cannot know where it will be writing during runtime in such a scenario,
but the option should be there to use LIB code that uses byte instead of word read/writes.
IAR promised this about a year ago, and we're still waiting !!!!
 
Kris
 
----- Original Message -----
From: Matthew Bivans
To: msp430@yahoogroups.com
Sent: Friday, August 02, 2002 5:29 AM
Subject: [msp430] IAR Compiler - Stack Auto vars mis-alignment

I've run across a bug in the latest (1.26a) rev. of the IAR compiler for the MSP430.  The compiler doesn't generate correct word addresses for auto variables located on the stack when the variable is declared in a sub-scope after code in a function.  It's not an easy set of circumstances to explain, but if you compile the follow code in ew1.26a you'll see nVal end up at offset 13 from the SP!.  The resulting assembly output is located below for both 1.24 and 1.26.  If you run it in C-SPY you can see the misalignment clearly.  It appears to be okay in ew1.24a.

After going back-and-forth with IAR for over a month on this I finally found out that the first possible date for a fix is 2/2003.  So, I wanted to at least make everyone here aware of this.

matt b.

Example Code:

#include <stdio.h>
void main(void)
{
    char pRcvData[11];

    {               
        char cChr = 0;
        sscanf(pRcvData,"%c",&cChr);
    }

    {
        /* Here's where the trouble occurs, in ew1.26a nVal is located
        at 13 bytes offset from the SP!, which doesn't work because
        word accesses (even the initialization to 0x1234) can't be
        done to odd addresses.  EW1.24a handles this fine */
       
        unsigned int nVal = 0x1234;
        sscanf(pRcvData,"%u",&nVal);
    }   
}

Results using ew1.26A:
main:
      SUB      #16,SP     
      MOV.B      #0,12(SP)     
      MOV      SP,R12     
      ADD      #12,R12     
      PUSH      R12     
      PUSH      #?0010     
      MOV      SP,R12     
      ADD      #4,R12     
      CALL      #sscanf     
      ADD      #4,SP     
      MOV      #4660,13(SP)      <<< note the odd SP offset, 4660 is actaully written to 12(SP)
      MOV      SP,R12     
      ADD      #13,R12     
      PUSH      R12     
      PUSH      #?0011     
      MOV      SP,R12     
      ADD      #4,R12     
      CALL      #sscanf     
      ADD      #4,SP     
      ADD      #16,SP     
      RET           
      RSEG      CSTR
?0010:
      DB      '%c'
      DB      0
?0011:
      DB      '%u'
      DB      0
      END

Results using ew1.24A:
main:
      SUB      #14,SP     
      MOV.B      #0,11(SP)     
      MOV      SP,R12     
      ADD      #11,R12     
      PUSH      R12     
      PUSH      #?0010     
      MOV      SP,R12     
      ADD      #4,R12     
      CALL      #sscanf     
      ADD      #4,SP     
      MOV      #4660,12(SP)   << even stack offset is okay     
      MOV      SP,R12     
      ADD      #12,R12     
      PUSH      R12     
      PUSH      #?0011     
      MOV      SP,R12     
      ADD      #4,R12     
      CALL      #sscanf     
      ADD      #4,SP     
      ADD      #14,SP     
      RET           
      RSEG      CSTR
?0010:
      DB      '%c'
      DB      0
?0011:
      DB      '%u'
      DB      0
      END








">Yahoo! Terms of Service.


We had an annoying problem with IAR and static char arrays.  An odd 
size array would create an odd record length in the binary output 
file.  The JTAG tools at the time didn't handle this properly and an 
error would occur.  Everything I've used since works fine, but I 
still tend to create even length arrays just because I don't trust 
what a different programming device might do.