Problem in concatenation with the '+' operator.

Beta Testing discussion on mikroPascal PRO for PIC.
Post Reply
Author
Message
Dany
Posts: 3854
Joined: 18 Jun 2008 11:43
Location: Nieuwpoort, Belgium
Contact:

Problem in concatenation with the '+' operator.

#1 Post by Dany » 18 Aug 2014 19:59

In case the last string in a string concatenation with the '+' operator (not with StrCat) is a constant string, the compiler forgets to add a terminating zero to the destination string.

The result: the destination can get a string that is too long, and contains a part of the 'old' contents of the string.
The problem is only visible if the previous string in was "longer" than the one where the error occurs.

Example code:

Code: Select all

program StringConcat;

{ Declarations section }
var text: string[50];
    Str1: string[15];
    Siz : word;
    
const ConstString = 'ghi';


begin
  { Main program }
  
  // --------------------------------------------------------
  // usage of constant string at the end of the concatenation
  // --------------------------------------------------------
  Str1 := 'abcdef';
  text := Str1 + ConstString; // text = 'abcdefghi' OK
  Siz := strlen(text); // strlen = 9 (as expected)

  Str1 := 'abc';
  text := Str1 + ConstString; // text = 'abcghighi'          <--ERROR (expected = 'abcghi')
  Siz := strlen(text); // expected strlen = 6; actual = 9    <--ERROR
  
     // literal string
  Str1 := 'abc';
  text := Str1 + 'ghi'; // text = 'abcghi' OK
  Siz := strlen(text); // expected and actual strlen = 6;
  
  // ------------------------------------------------------------
  // usage of constant string not at the end of the concatenation
  // ------------------------------------------------------------
  Str1 := 'abcdef';
  text := ConstString + Str1; // text = 'ghiabcdef' OK
  Siz := strlen(text); // strlen = 9 (as expected)

  Str1 := 'abc';
  text := ConstString + Str1; // text = 'ghiabc' OK
  Siz := strlen(text); // strlen = 6 (as expected)

     // literal string
  Str1 := 'abc';
  text := 'ghi' + Str1; // text = 'ghiabc' OK
  Siz := strlen(text); // expected and actual strlen = 6;
  
end.
The reason is the following: the compiler forgets the statement

Code: Select all

CLRF        POSTINC1
after

Code: Select all

RCALL       ___CCS2S
Some assembly code:

1. Concatenation of 2 variable strings (terminating zero OK)

Code: Select all

;StringConcat.mpas,14 :: 		text := Str1 + Str1;
0x0068	0x0E27      	MOVLW       _text
0x006A	0x6EE1      	MOVWF       FSR1L 
0x006C	0x0E00      	MOVLW       hi_addr(_text)
0x006E	0x6EE2      	MOVWF       FSR1H 
0x0070	0x0E17      	MOVLW       _Str1
0x0072	0x6ED9      	MOVWF       FSR2L 
0x0074	0x0E00      	MOVLW       hi_addr(_Str1)
0x0076	0x6EDA      	MOVWF       FSR2H 
0x0078	0xDFF1      	RCALL       ___CS2S
0x007A	0x0E17      	MOVLW       _Str1
0x007C	0x6ED9      	MOVWF       FSR2L 
0x007E	0x0E00      	MOVLW       hi_addr(_Str1)
0x0080	0x6EDA      	MOVWF       FSR2H 
0x0082	0xDFEC      	RCALL       ___CS2S
0x0084	0x6AE6      	CLRF        POSTINC1; <--- the terminating zero 
2. Concatenation of a constant string and a variable string (terminating zero OK)

Code: Select all

;StringConcat.mpas,16 :: 		text := ConstString + Str1;
0x0074	0x0E27      	MOVLW       _text
0x0076	0x6EE1      	MOVWF       FSR1L 
0x0078	0x0E00      	MOVLW       hi_addr(_text)
0x007A	0x6EE2      	MOVWF       FSR1H 
0x007C	0x0E34      	MOVLW       _ConstString
0x007E	0x6EF6      	MOVWF       TBLPTR 
0x0080	0x0E02      	MOVLW       hi_addr(_ConstString)
0x0082	0x6EF7      	MOVWF       TBLPTRH 
0x0084	0x0E00      	MOVLW       higher_addr(_ConstString)
0x0086	0x6EF8      	MOVWF       TBLPTRU 
0x0088	0xDFC9      	RCALL       ___CCS2S
0x008A	0x0E17      	MOVLW       _Str1
0x008C	0x6ED9      	MOVWF       FSR2L 
0x008E	0x0E00      	MOVLW       hi_addr(_Str1)
0x0090	0x6EDA      	MOVWF       FSR2H 
0x0092	0xDFDC      	RCALL       ___CS2S
0x0094	0x6AE6      	CLRF        POSTINC1; <--- the terminating zero 
3. Concatenation of a variable string and a constant string (NO terminating zero)

Code: Select all

;StringConcat.mpas,20 :: 		text := Str1 + ConstString; // text = 'abcdefghi' OK
0x00A0	0x0E27      	MOVLW       _text
0x00A2	0x6EE1      	MOVWF       FSR1L 
0x00A4	0x0E00      	MOVLW       hi_addr(_text)
0x00A6	0x6EE2      	MOVWF       FSR1H 
0x00A8	0x0E17      	MOVLW       _Str1
0x00AA	0x6ED9      	MOVWF       FSR2L 
0x00AC	0x0E00      	MOVLW       hi_addr(_Str1)
0x00AE	0x6EDA      	MOVWF       FSR2H 
0x00B0	0xDFD5      	RCALL       ___CS2S
0x00B2	0x0E24      	MOVLW       _ConstString
0x00B4	0x6EF6      	MOVWF       TBLPTR 
0x00B6	0x0E02      	MOVLW       hi_addr(_ConstString)
0x00B8	0x6EF7      	MOVWF       TBLPTRH 
0x00BA	0x0E00      	MOVLW       higher_addr(_ConstString)
0x00BC	0x6EF8      	MOVWF       TBLPTRU 
0x00BE	0xDFAE      	RCALL       ___CCS2S
                                ; <--- no terminating zero: missing "CLRF  POSTINC1"
Tested with mP for PIC PRO (v6.40) on the P18F4620. I do not know if this issue is also valid in other environments...
Kind regards, Dany.
Forget your perfect offering. There is a crack in everything, that's how the light gets in... (L. Cohen)
Remember when we were young? We shone like the sun. (David Gilmour)

User avatar
filip
mikroElektronika team
Posts: 11874
Joined: 25 Jan 2008 09:56

Re: Problem in concatenation with the '+' operator.

#2 Post by filip » 20 Aug 2014 09:00

Hi,

Thank you for your report and I apologize for the inconvenience caused by this.

Regards,
Filip.

Post Reply

Return to “mikroPascal PRO for PIC Beta Testing”