Why I do not see binary codes of my sketch in hex file?

I have compiled, uploaded the following sketch and then clicked on "Export Compiled Binary" to get two .hex files (test2.ino.standard.hex, test2.ino.with_bootloader.standard.hex). I have scanned both files frame-by-frame manually; unfortunately, I do not see the expected pattern there. Am I missing anything? Any help would be highly appreciated. It is an academic need.

void setup() 
{
  byte y1 = 0x75;
  byte y2 = 0x75;
  byte y3 = 0x23;
  byte y4 = 0x45;
}

void loop() 
{
  
}

Hello GolamMostafa

I´ve searched and found the unexported HEX-file by searching with this filename as follows:

sketch_may03c.ino.hex

HTH

Could it be that your expectation is wrong?

Let me try this explanation: The compiler takes your code as a 'flow chart' to generate a 'to do' list for the microcontroller. What you call 'byte y1' is converted to an memory address that spans the byte value (8 bits) so, you will not see 'y1' in the compiled code. 0x75 is then stored at that address. I hope this helps a little.

In order for us to help you, please provide us with good information.

What is your sysOP? And which version?
What version of your arduino IDE?
Which "arduino" or other controller was selected?

When I use MICROCHIP STUDIO Assembler, I can very well find the data pattern in the generated hex file; where, operand is intermixed with opcode. I have expected similar thing in the hex file produced by Arduino IDE.

Windows 10
1.8.19
Arduino UNO with ATmega328P MCU

1 Like

I would not rush to the conclusion that assembler output == C++ compiler output.

I understand what you are saying. I am looking for 75, 75, 23, and 45 which I can't find in the hex file produced by Arduino IDE.

Maybe that toolchain isn't so good at optimising.

However, the data bytes 75, 75, 23 and 45 should be somewhere in the following hex file being intermixed with opcode.

test2.ino.standard.hex

:10 0000 00 0C94 3400 0C94 4600 0C94 4600 0C94 4600 6A
:100010000C9446000C9446000C9446000C94460048
:100020000C9446000C9446000C9446000C94460038
:100030000C9446000C9446000C9446000C94460028
:100040000C9448000C9446000C9446000C94460016
:100050000C9446000C9446000C9446000C94460008
:100060000C9446000C94460011241FBECFEFD8E03C

:10 0070 00 DEBF CDBF 21E0 A0E0 B1E0 01C0 1D92 A930 FC
:10008000B207E1F70E9492000C94DC000C9400008F
:100090001F920F920FB60F9211242F933F938F93BD
:1000A0009F93AF93BF938091050190910601A0911A
:1000B0000701B09108013091040123E0230F2D378F
:1000C00058F50196A11DB11D2093040180930501EF
:1000D00090930601A0930701B0930801809100015D
:1000E00090910101A0910201B09103010196A11D1F
:1000F000B11D8093000190930101A0930201B09380
:100100000301BF91AF919F918F913F912F910F90DC
:100110000FBE0F901F90189526E8230F0296A11D81
:10012000B11DD2CF789484B5826084BD84B58160DE
:1001300084BD85B5826085BD85B5816085BD8091B2
:100140006E00816080936E0010928100809181002A
:100150008260809381008091810081608093810022
:10016000809180008160809380008091B1008460E4
:100170008093B1008091B00081608093B000809145
:100180007A00846080937A0080917A008260809304
:100190007A0080917A00816080937A0080917A0061
:1001A000806880937A001092C100C0E0D0E0209770
:0C 01B0 00 F1F3 0E94 0000 FBCF F894 FFCF 99
:00 0000 01 FF

Can you explain why you think that should be so?

The compiler knows that you are not using them, so the compiler removes those line.

In the Arduino IDE 2.0, I turn on the all compiler warnings, then I get:

warning: unused variable 'y1'
warning: unused variable 'y2'
warning: unused variable 'y3'
warning: unused variable 'y4'

So you could have known that :wink:

If you force the compiler to allocate a memory location for them and force to use them:

void setup() 
{
  volatile byte y1 = 0x75;
  volatile byte y2 = 0x75;
  volatile byte y3 = 0x23;
  volatile byte y4 = 0x45;
}

void loop() 
{
  
}

Then they can be found:

void setup() 
{
  volatile byte y1 = 0x75;
 1b6:	85 e7       	ldi	r24, 0x75	; 117
 1b8:	8c 83       	std	Y+4, r24	; 0x04
  volatile byte y2 = 0x75;
 1ba:	8b 83       	std	Y+3, r24	; 0x03
  volatile byte y3 = 0x23;
 1bc:	83 e2       	ldi	r24, 0x23	; 35
 1be:	8a 83       	std	Y+2, r24	; 0x02
  volatile byte y4 = 0x45;
 1c0:	85 e4       	ldi	r24, 0x45	; 69
 1c2:	89 83       	std	Y+1, r24	; 0x01

The opcode for the ldi instruction is a little strange, so it does not show in the binary code.

[UPDATE]
There they are in the HEX file (with the "volatile" keyword of course):
afbeelding

2 Likes

If you are looking for the hex code "75" as a data value, you won't find it in the LDI assembler listing, because it is distributed as two nibbles in separate bytes of 16 bit instruction.

1 Like

1. How have you produced the assembly codes in post #13?
2. Has your hex file been produced by Arduino IDE?
3. Using volatile keywords, I have compiled and uploaded the following sketch in UNO. Now, I can see the data pattern (75, near the end of hex file marked bold) being known that a data byte comes intermixed with other digits of 16-bit instruction of AVR. (Where is other 75?)

void setup() 
{
  volatile byte y1 = 0x75;
  volatile byte y2 = 0x75;
  volatile byte y = y1 + y2; //EA
  y = y*1;
}

void loop() 
{
  
}

:10 0000 00 0C94 3400 0C94 4600 0C94 4600 0C94 4600 6A
:10 0010 00 0C94 4600 0C94 4600 0C94 4600 0C94 4600 48
:100020000C9446000C9446000C9446000C94460038
:100030000C9446000C9446000C9446000C94460028
:100040000C9448000C9446000C9446000C94460016
:100050000C9446000C9446000C9446000C94460008
:10 0060 00 0C94 4600 0C94 4600 1124 1FBE CFEF D8E0 3C

:10 0070 00 DEBF CDBF 21E0 A0E0 B1E0 01C0 1D92 A930 FC
:10 0080 00 B207 E1F7 0E94 9200 0C94 EC00 0C94 0000 7F
:10 0090 00 1F92 0F92 0FB6 0F92 1124 2F93 3F93 8F93 BD
:10 00A0 00 9F93 AF93 BF93 8091 0501 9091 0601 A091 1A
:10 00B0 00 0701 B091 0801 3091 0401 23E0 230F 2D37 8F
:10 00C0 00 58F5 0196 A11D B11D 2093 0401 8093 0501 EF
:10 00D0 00 9093 0601 A093 0701 B093 0801 8091 0001 5D
:10 00E0 00 9091 0101 A091 0201 B091 0301 0196 A11D 1F
:10 00F0 00 B11D 8093 0001 9093 0101 A093 0201 B093 80
:10 0100 00 0301 BF91 AF91 9F91 8F91 3F91 2F91 0F90 DC
:10 0110 00 0FBE 0F90 1F90 1895 26E8 230F 0296 A11D 81
:10 0120 00 B11D D2CF CF93 DF93 00D0 1F92 CDB7 DEB7 F2
:10 0130 00 7894 84B5 8260 84BD 84B5 8160 84BD 85B5 C2
:10 0140 00 8260 85BD 85B5 8160 85BD 8091 6E00 8160 CE
:10 0150 00 8093 6E00 1092 8100 8091 8100 8260 8093 74
:10 0160 00 8100 8091 8100 8160 8093 8100 8091 8000 76
:10 0170 00 8160 8093 8000 8091 B100 8460 8093 B100 A1
:10 0180 00 8091 B000 8160 8093 B000 8091 7A00 8460 9B
:10 0190 00 8093 7A00 8091 7A00 8260 8093 7A00 8091 C7
:10 01A0 00 7A00 8160 8093 7A00 8091 7A00 8068 8093 E1
:10 01B0 00 7A00 1092 C100 85E7 8B83 8A83 8B81 9A81 B4
:10 01C0 00 890F 8983 8981 8983 00E0 10E0 0115 1105 79
:0C 01D0 00 E9F3 0E94 0000 FACF F894 FFCF 82
:00000001FF

4. During uploading, which file
(standard.hex or with_bootloader.standardard.hex) is transmitted to UNO?

It is the same as the first 75 so the compiler optimizes it away.

1 Like

For example:
75 is an immediate data; so, I expect immediate addressing mode will be used by the Compiler. The data byte will be stored in the next flash memory location following the opcode. However, in AVR architecture, the 16-bit instruction contains opcode and operand in a different way which I call intermixed.

Therefore, 75 should be somewhere there in the hex file (not as consecutive digit; rather, being intermixed with opcode's digits) which contains the executable binary/machine codes of the sketch.

It is value of y2 in post #15. I have taken identical value for the ease of detection in the hex file.

You won't find it for y2. See post #13, where the compiler optimization is perfectly clear.

1 Like

Is it optimized because of identical values? I tried with 73 instead of 75 and I can't find it in the hex file.