Electronic – AVR gcrt1.S behavior

assemblyavrc

So basically i have decompiled unoptimized simple program and saw that it runs through gcrt1.S, and i dived in to assembly language and tried to understand what exactly it does. here is my code and my assumption of what it does

00000034  CLR R1        Clear Register 
00000035  OUT 0x3F,R1       Out to I/O location 
00000036  SER R28       Set Register        
00000037  LDI R29,0x08      Load immediate      
00000038  OUT 0x3E,R29      Out to I/O location 
00000039  OUT 0x3D,R28      Out to I/O location 
0000003A  CALL 0x00000040       Call subroutine 
0000003C  JMP 0x00000050        Jump 
0000003E  JMP 0x00000000        Jump 


Clear R1
Clear stratus register
Set R28 1111 1111

Here is where my questions start:
Load R29 from 0x08 (PORTC ?)
OUT to SPH <-R29
OUT to SPL <-R28
Call Main

The confuision that i have is why it loads byte from PORTC register, since the default would be 0x00 anyway

Microcontroller is atmega328p link to a datasheet

Best Answer

This has nothing to do with PORTC register.

LDI means "Load Immediate", which says take a literal value and load it directly into a register.

LDI R29,0x08

Takes the literal value 0x08 and loads it into R29.

The function is basically initialising the stack pointer to point to the end of the RAM which can be seen from the below diagram to be 0x08FF. That means we need 0x8 in SPH and 0xFF in SPL.

Memory Map of ATMega328p

As to why it uses SER R28 rather than LDI R28 0xFF, I don't know. Both are functionally equivalent, the same size and have the same side-effects.


To load from a port, the IN instruction is used:

IN R29,0x08

Would be load in the value from PORTC register into R29.