Never assume: Constants & Literals in FLASH ?

I would like to assume that constants and inline literals always wind up in FLASH with the program.
Alas daddy taught me to “never assume”. So I wrote a simple “Hello World” sketch to look at the disassembly.
(Please to see attached text file)

void setup()
 { Serial.begin(9600);
  }
void loop()
  { Serial.println("Hello World!");
    delay (1000);
  }

I can not find where it is actually putting the characters for the string “Hello World”.

HelloWorld_000.txt (47.7 KB)

The avr-objdump tool doesn't show the data sections of the flash, only the code.

If you look at the hex file, somewhere you will see the ascii equivalent of "Hello World", normally near the start for PROGMEM variables and at the end for data initialisers.

But actually the sketch will store that string both in the Flash, and then in the RAM as well.

Here we go, extract from the Hex file:

:1008280048656C6C6F20576F726C64210000000083

Note the highlighted section. Stick it into the hex field of this website:

Thank you.
It has taken me a while to find a version of 'readelf' that would run under windows but I found one in Strawberry Perl.

I would like to assume that constants and inline literals always wind up in FLASH with the program

Well obviously they do - where else could they be?
Unfortunately, unless you're careful, they also wind up in RAM, which is why you should always Serial.println(F("Hello World!")); if at all possible.

At this point I am just trying to get an understanding of what actually happens so that I may accidently make the correct choice in the future.

The F() macro tells the compiler to put the string in the Flash ONLY.

Serial.print("Hello World!");

uses 15 bytes of flash AND 15 bytes of RAM. When the program starts, the string is loaded from the flash into the ram as an array of 15 characters. A pointer to this new array is then sent to the print function. What it means is that you can use it with functions like strcpy() and sprintf(), e.g. sprintf(dest,"%d",2) stores a 3 character string of '%' then 'd', then '\0'.

Serial.print(F("Hello World!"));

uses 15 bytes of flash AND 0 bytes of RAM. When the program starts, the string is NOT loaded from the flash. This array is then sent to the print function. Instead a special print function is used which, starting with the address of the string in the flash, reads bytes one by one and writes them to the Serial port. Consequently, you can't use functions like strcpy, and instead have to use the strcpy_P set of functions which can read bytes in from the flash.

Thank you ... that is a bit clearer.

Actually I will probably wind up using a PROGMEM table with a temp buffer in ram for the few strings that I will need.