I understand that this is a late answer. However, I still think it might be interesting to have a detailed step-by-step answer to all the questions.
- What is.-8 syntax or similar? (e.g. address 0x98 or 0xAA.)
This means: "jump from here 8 bytes." Remember that the program counter has already been increased by the length of the instruction (2 bytes), so brne .-8 move you 6 bytes (not 8) to the brne command itself. In the same vein, rcall .+0 will call the program counter rcall .+0 stack without changing the program stream. This is a trick designed only to reserve two bytes of stack space in one command.
- There are some funny things around the lines with addresses from 80 to 88 (end of __do_copy_data). It seems to me that it loads all the program code into RAM from the address 0xC4. Why?
No, nothing is copied, this is an empty loop. Lines 84 through 88 have a test that exits the loop when the X pointer (r27: r26) is 0x0100. Since X is initialized to 0x0100, this will not loop completely.
This loop is for copying a section of data from flash memory to RAM. This basically happens like this:
X = DATA_START;
but your program has an empty data section ( DATA_SIZE == 0 in the above pseudo-code).
In addition, you should note that your program ends at 0x00c3, so the Z pointer is initialized to indicate immediately after the program code. Here should be the initial values ββof the initialized variables.
- In the __do_clear_bss_start / loop, we clear all the work we just did by setting the bytes in RAM to 0 (value r1). What for? All of this will finally call
main . Any general explanations?
No, nothing will be overwritten. This loop clears the BSS, which usually arrives immediately after the data partition without overlapping. Pseudocode:
X = BSS_START; while (X != BSS_START + BSS_SIZE) ram[X++] = 0;
where BSS_START == DATA_START + DATA_SIZE . This is also an empty loop in your program, because you have an empty bss.
- Why not unmount show.bss, .rodata, or other sections?
Because objdump -d only parses sections that expect code to be saved.
- Line 6a, why is SREG cleared? Isn't he tuned to what should be after each instruction?
Most instructions change only some of the SREG bits. In addition, it clears the enable global interrupt bit.
- Lines 6c and 6e: what correspond to 0xFF and 0x08? r28 and r29 are the stack pointer, low and high.
The stack pointer is loaded with 0x08ff, which is the last RAM cell in the ATmega328P. The stack will grow down from there.
- I played a little and added a static global variable. Why do we store in RAM starting with 0x0100, and not 0x0000?
RAM is at 0x0100-0x08ff at 328P. Below this address you have memory mapping registers (CPU registers and I / O registers). For more details see the technical description , section "8.3 SRAM data memory".
- On line 8a, why
ldi r17, 1 ? We did this before (just a stupid remark). Or can something else change r17?
Line 8a is useless. It is here that, due to the way the linker creates the program by gluing the different parts __do_copy_data : __do_copy_data and __do_clear_bss are independent procedures, they do not rely on what remains in the registers.
- We start copying the program into flash memory in RAM, starting with 0xC4 (.bss and other sections, I think), but cpi / cpc X with respect to 1 will make ALL flash memory copied to the entire RAM. Is it just too lazy for the compiler not to stop copying when .bss sections finish copying?
You misunderstood this part of the code. The cpi, cpc, and brne commands will loop only until X is different from r17: 0x00 (i.e. 0x0100, since r17 = 1). CF pseudo codes above.