CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug Reports on this forum. Send them to support@ccsinfo.com

Understanding how CCS stores strings.

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
allenhuffman



Joined: 17 Jun 2019
Posts: 499
Location: Des Moines, Iowa, USA

View user's profile Send private message Visit poster's website

Understanding how CCS stores strings.
PostPosted: Tue Feb 25, 2020 9:10 am     Reply with quote

We recently stumbled into an issue where the code generator would use the wrong string for printf/sprintf, so I am trying to understand how strings are handled. There appears to be some limit where we add one more string, and then it uses the first string in the .lst file.

(i.e., printf("Value: %d", value); is the intent, but it outputs "xxxxxxx42" because it finds a string "xxxxxxxxxxxx". It's clearly using the correct one for the format string (since it puts the %d at the right spot) but it's outputting from a different string.)

I did a quick test showing printf of some constant strings, and declaring a few strings:
Code:
#include "main.h"

char *string1  = "A*A*A*A*";
char string2[] = "B*B*B*B*";

const char *string3  = "C*C*C*C*";
const char string4[] = "D*D*D*D*";

void main()
{
   printf ("1111: %s\r\n", string1);
   printf ("2222: %s\r\n", string2);
   printf ("3333: %s\r\n", string3);
   printf ("4444: %s\r\n", string4);
 
   while(TRUE) // CCS compiler #define
   {
      //TODO: User Code
   }
}

// End of main.c


Constant strings like in the printf seem to store at the top, as does "const char string[]" using brackets, then all the rest are grouped after it.

Code:
const char string4[] = "D*D*D*D*";

00200:  CLR     32
00202:  MOV     #20C,W3
00204:  ADD     W3,W0,W0
00206:  TBLRDL.B[W0],W0L
00208:  CLR.B   1
0020A:  RETURN 
0020C:  DATA    44,2A,00
0020E:  DATA    44,2A,00
00210:  DATA    44,2A,00
00212:  DATA    44,2A,00
00214:  DATA    00,00,00


printf ("1111: %s\r\n", string1);

00216:  CLR     32
00218:  MOV     #222,W3
0021A:  ADD     W3,W0,W0
0021C:  TBLRDL.B[W0],W0L
0021E:  CLR.B   1
00220:  RETURN 
00222:  DATA    31,31,00
00224:  DATA    31,31,00
00226:  DATA    3A,20,00
00228:  DATA    25,73,00
0022A:  DATA    0D,0A,00
0022C:  DATA    00,00,00


printf ("2222: %s\r\n", string2);

0022E:  CLR     32
00230:  MOV     #23A,W3
00232:  ADD     W3,W0,W0
00234:  TBLRDL.B[W0],W0L
00236:  CLR.B   1
00238:  RETURN 
0023A:  DATA    32,32,00
0023C:  DATA    32,32,00
0023E:  DATA    3A,20,00
00240:  DATA    25,73,00
00242:  DATA    0D,0A,00
00244:  DATA    00,00,00


printf ("3333: %s\r\n", string3);

00246:  CLR     32
00248:  MOV     #252,W3
0024A:  ADD     W3,W0,W0
0024C:  TBLRDL.B[W0],W0L
0024E:  CLR.B   1
00250:  RETURN 
00252:  DATA    33,33,00
00254:  DATA    33,33,00
00256:  DATA    3A,20,00
00258:  DATA    25,73,00
0025A:  DATA    0D,0A,00
0025C:  DATA    00,00,00


printf ("4444: %s\r\n", string4);

0025E:  CLR     32
00260:  MOV     #26A,W3
00262:  ADD     W3,W0,W0
00264:  TBLRDL.B[W0],W0L
00266:  CLR.B   1
00268:  RETURN 
0026A:  DATA    34,34,00
0026C:  DATA    34,34,00
0026E:  DATA    3A,20,00
00270:  DATA    25,73,00
00272:  DATA    0D,0A,00
00274:  DATA    00,00,00

. . . snip . . .


.................... // End of main.h
....................
....................

char *string1  = "A*A*A*A*";
*
002C2:  MOV     #2A41,W4
002C4:  MOV     W4,802
002C6:  MOV     #2A41,W4
002C8:  MOV     W4,804
002CA:  MOV     #2A41,W4
002CC:  MOV     W4,806
002CE:  MOV     #2A41,W4
002D0:  MOV     W4,808
002D2:  CLR.B   80A
002D4:  MOV     #802,W4
002D6:  MOV     W4,800
....................


char string2[] = "B*B*B*B*";

002D8:  MOV     #2A42,W4
002DA:  MOV     W4,80C
002DC:  MOV     #2A42,W4
002DE:  MOV     W4,80E
002E0:  MOV     #2A42,W4
002E2:  MOV     W4,810
002E4:  MOV     #2A42,W4
002E6:  MOV     W4,812
002E8:  CLR.B   814
.................... char *string1  = "A*A*A*A*";
.................... char string2[] = "B*B*B*B*";


const char *string3  = "C*C*C*C*";

002EA:  MOV     #2A43,W4
002EC:  MOV     W4,816
002EE:  MOV     #2A43,W4
002F0:  MOV     W4,818
002F2:  MOV     #2A43,W4
002F4:  MOV     W4,81A
002F6:  MOV     #2A43,W4
002F8:  MOV     W4,81C
002FA:  CLR.B   81E
....................
.................... const char *string3  = "C*C*C*C*";
.................... const char string4[] = "D*D*D*D*";
....................
.................... void main()



Has anyone looked into how the strings work that might shed some light on this? I am trying to create a short one-file test case (if possible; may be a Multi-Unit bug) to send to CCS.

Thanks.
_________________
Allen C. Huffman, Sub-Etha Software (est. 1990) www.subethasoftware.com
Embedded C, Arduino, MSP430, ESP8266/32, BASIC Stamp and PIC programmer.
www.whywouldyouwanttodothat.com ?
Ttelmah



Joined: 11 Mar 2010
Posts: 17983

View user's profile Send private message

PostPosted: Tue Feb 25, 2020 9:23 am     Reply with quote

I think it must be a multi-unit bug, since I have stuff with tens of KB of strings
and have never seen a problem. But I don't use MCU's.
There are some 'bodges' that appear at particular points in the ROM space
I asked before about whether you were using PSV. If you are not, consider it.
With PSV, the ROM space used for this data is mapped into a window in the
RAM address map, and the functions using const strings can treat them as
normal RAM strings. Makes access faster, and is likely to avoid such problems.
allenhuffman



Joined: 17 Jun 2019
Posts: 499
Location: Des Moines, Iowa, USA

View user's profile Send private message Visit poster's website

PostPosted: Tue Feb 25, 2020 9:52 am     Reply with quote

I see on startup that our strings are being copied into RAM. The code at the start of each block is being called in a huge series of CALL statements during program init. This explains why we are so low on memory ;-)

I am looking at the source where the printf is, trying to figure out how it is getting the wrong string. I think I can show that to CCS and they may understand what is going on.
_________________
Allen C. Huffman, Sub-Etha Software (est. 1990) www.subethasoftware.com
Embedded C, Arduino, MSP430, ESP8266/32, BASIC Stamp and PIC programmer.
www.whywouldyouwanttodothat.com ?
Ttelmah



Joined: 11 Mar 2010
Posts: 17983

View user's profile Send private message

PostPosted: Tue Feb 25, 2020 1:27 pm     Reply with quote

Are you running in ANSI mode?.
If you do, this makes a 'const', a RAM variable that cannot normally be
changed. Result you use RAM for every single one.
allenhuffman



Joined: 17 Jun 2019
Posts: 499
Location: Des Moines, Iowa, USA

View user's profile Send private message Visit poster's website

PostPosted: Tue Feb 25, 2020 1:43 pm     Reply with quote

Ttelmah wrote:
Are you running in ANSI mode?.
If you do, this makes a 'const', a RAM variable that cannot normally be
changed. Result you use RAM for every single one.


I didn't know there was an ANSI mode. These are just "make a new project with the wizard and use its defaults", then I add things like #case and stuff to enable printf.
_________________
Allen C. Huffman, Sub-Etha Software (est. 1990) www.subethasoftware.com
Embedded C, Arduino, MSP430, ESP8266/32, BASIC Stamp and PIC programmer.
www.whywouldyouwanttodothat.com ?
temtronic



Joined: 01 Jul 2010
Posts: 8513
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Tue Feb 25, 2020 7:01 pm     Reply with quote

ANSI is in the manual, and it's important to understand what it changes.
Also
stop using the 'wizard'. Sooner AND later, it'll trip you up ! Some other 'programmer', programmed the 'wizard' with HIS defaults NOT yours. So eventually your program that 'should work'.... doesn't.

I don't use it, debuggers or simulators. None can be 100% trusted.
allenhuffman



Joined: 17 Jun 2019
Posts: 499
Location: Des Moines, Iowa, USA

View user's profile Send private message Visit poster's website

PostPosted: Wed Feb 26, 2020 1:36 pm     Reply with quote

temtronic wrote:
ANSI is in the manual, and it's important to understand what it changes.


Thanks. I didn't find anything int he online manual/help in the IDE, but I see this in the PDF:

Quote:
ANSI

Default data type is SIGNED all other modes default is UNSIGNED.
Compilation is case sensitive, all other modes are case insensitive.
Pointer size is set to *=16 if the part has RAM over 0FF.


Hmm. Does this mean an "int" is unsigned in default? Not much detail, though -- #case and signed. Does it do more?
_________________
Allen C. Huffman, Sub-Etha Software (est. 1990) www.subethasoftware.com
Embedded C, Arduino, MSP430, ESP8266/32, BASIC Stamp and PIC programmer.
www.whywouldyouwanttodothat.com ?
allenhuffman



Joined: 17 Jun 2019
Posts: 499
Location: Des Moines, Iowa, USA

View user's profile Send private message Visit poster's website

PostPosted: Wed Feb 26, 2020 1:57 pm     Reply with quote

temtronic wrote:
ANSI is in the manual, and it's important to understand what it changes.


Wow. Huge difference in code generation from the default.

With #device ANSI:
Code:
               ROM used:   41274 bytes (24%)
                           Largest free fragment is 43520
               RAM used:   13080 (80%) at main() level
                           15179 (93%) worst case
               Stack used: 94 loc


Without (CCS4 default):
Code:
               ROM used:   37486 bytes (21%)
                           Largest free fragment is 43520
               RAM used:   6533 (40%) at main() level
                           8635 (53%) worst case
               Stack used: 94 locations (54 in main + 40 for interrupts)
               Stack size: 128

_________________
Allen C. Huffman, Sub-Etha Software (est. 1990) www.subethasoftware.com
Embedded C, Arduino, MSP430, ESP8266/32, BASIC Stamp and PIC programmer.
www.whywouldyouwanttodothat.com ?
allenhuffman



Joined: 17 Jun 2019
Posts: 499
Location: Des Moines, Iowa, USA

View user's profile Send private message Visit poster's website

PostPosted: Thu Jun 23, 2022 11:48 am     Reply with quote

Our new projects have made done using one C file and #includes, but our legacy projects are all multi-unit compile. I'm back to trying to figure this out, waiting to see what CCS says.

It will be wanting to print a 6-character string ("set.\r\n") but points to the location of a completely different string. Fun Smile

I have at least caught the compiler pointing to the wrong constant ROM data:

Code:

                         ..............................         DEBUG_PRINTF ("1 sweepComplete FALSE\r\n");
01CD4 200001         MOV     #0,W1          : W1 = 0
01CD6 780001         MOV     W1,W0          : W0 = W1
01CD8 EF6001         CLR.B   1              : W0H = 0
*** HERE:
01CDA 0208DE 000000  CALL    8DE            :
01CDE E80081         INC     W1,W1          : W1 = W1 + 1
01CE0 781F81         MOV     W1,[W15++]     : Push W1 to TOS
01CE2 F86518         PUSH    6518           : PUSH [6518] to TOS
01CE4 9FFFE0         MOV.B   W0L,[W15-#2]   : [W15+-2] = W0L
01CE6 F96518         POP     6518           : POP TOS to [6518]
01CE8 0211F0 000000  CALL    11F0           :
01CEC 7800CF         MOV     [--W15],W1     : POP TOS to [--W15]
01CEE 200160         MOV     #16,W0         : W0 = 16
01CF0 E60810         CPSGT   W1,W0          : Skip if W1 > W0
01CF2 37FFF1         BRA     1CD6           : GoTo 1CD6

Elsewhere...


                         ..............................         DEBUG_PRINTF ("set.\r\n");
06260 200001         MOV     #0,W1          : W1 = 0
06262 780001         MOV     W1,W0          : W0 = W1
06264 EF6001         CLR.B   1              : W0H = 0
*** HERE:
06266 0208DE 000000  CALL    8DE            :
0626A E80081         INC     W1,W1          : W1 = W1 + 1
0626C 781F81         MOV     W1,[W15++]     : Push W1 to TOS
0626E F808C2         PUSH    8C2            : PUSH [8C2] to TOS
06270 A9E8C3         BCLR.B  8C3.7          : [8C3.7] = 0
06272 F86518         PUSH    6518           : PUSH [6518] to TOS
06274 9FFFE0         MOV.B   W0L,[W15-#2]   : [W15+-2] = W0L
06276 F96518         POP     6518           : POP TOS to [6518]
06278 0211F0 000000  CALL    11F0           :
0627C F908C2         POP     8C2            : POP TOS to [8C2]
0627E 7800CF         MOV     [--W15],W1     : POP TOS to [--W15]
06280 200050         MOV     #5,W0          : W0 = 5
06282 E60810         CPSGT   W1,W0          : Skip if W1 > W0
06284 37FFEE         BRA     6262           : GoTo 6262

...and...

                         ..............................         DEBUG_PRINTF ("set.\r\n");
062EE 200001         MOV     #0,W1          : W1 = 0
062F0 780001         MOV     W1,W0          : W0 = W1
062F2 EF6001         CLR.B   1              : W0H = 0
*** HERE:
062F4 0208DE 000000  CALL    8DE            :
062F8 E80081         INC     W1,W1          : W1 = W1 + 1
062FA 781F81         MOV     W1,[W15++]     : Push W1 to TOS
062FC F808C2         PUSH    8C2            : PUSH [8C2] to TOS
062FE A9E8C3         BCLR.B  8C3.7          : [8C3.7] = 0
06300 F86518         PUSH    6518           : PUSH [6518] to TOS
06302 9FFFE0         MOV.B   W0L,[W15-#2]   : [W15+-2] = W0L
06304 F96518         POP     6518           : POP TOS to [6518]
06306 0211F0 000000  CALL    11F0           :
0630A F908C2         POP     8C2            : POP TOS to [8C2]
0630C 7800CF         MOV     [--W15],W1     : POP TOS to [--W15]
0630E 200050         MOV     #5,W0          : W0 = 5
06310 E60810         CPSGT   W1,W0          : Skip if W1 > W0
06312 37FFEE         BRA     62F0           : GoTo 62F0


If I am allowed to make the change, I may try to get the project building using the one-C, #include method and see what that does.

Fun fun.
_________________
Allen C. Huffman, Sub-Etha Software (est. 1990) www.subethasoftware.com
Embedded C, Arduino, MSP430, ESP8266/32, BASIC Stamp and PIC programmer.
www.whywouldyouwanttodothat.com ?
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group