2

I am trying to remove the interrupt vector table in my program to reduce the flash memory usage.

I have successfully used the -nostartfiles flag, which removes a lot of assembly code in the output.

To use the program, I have to set the stack pointer. I found this code to do so:

asm volatile ( ".set __stack, %0" :: "i" (RAMEND) );

But when compiled, it does nothing, while other assembly code like

asm volatile ( "clr __zero_reg__" );      
asm volatile ( "rjmp main");

Does work.

This is my current C code:

void __init(void) __attribute__ ((naked)) __attribute__ ((section (".init9")));
void __init(void)
{
    asm volatile(".set __stack, %0" :: "i" (RAMEND) );
    asm volatile ( "clr __zero_reg__" );      
    asm volatile ( "rjmp main");             
}

Which compiles to assembly (the 7892 and 7894 lines):

void __jMain(void) __attribute__ ((naked)) __attribute__ ((section (".init9")));
void __jMain(void)
{
    asm volatile(".set __stack, %0" :: "i" (RAMEND) );
    asm volatile ( "clr __zero_reg__" );        
    7892:   11 24           eor r1, r1
    asm volatile ( "rjmp main");                
    7894:   02 c0           rjmp    .+4         ; 0x789a <main>
}

Why isn't the .set __stack compiled? Am I missing some compiler flag? Have tried a lot of things.. Also reviewed bootloaders with the same piece of code who are doing the same thing, but somehow, mine does not compile correctly.

2
  • 2
    .set is a directive, it won't produce any code. Commented Jul 31, 2015 at 15:56
  • Thanks a lot! Didn't know that existed. Thought it should do something else. Commented Jul 31, 2015 at 16:04

2 Answers 2

1

How about:

asm volatile(
        "ldi  r28, lo8(RAMEND)" "\n\t"
        "ldi  r29, hi8(RAMEND)" "\n\t"
        "out __SP_L__, r28" "\n\t"
        "out __SP_H__, r29" "\n\t"
 );

Main source: https://ucexperiment.wordpress.com/2015/01/02/arduino-stack-painting/

Sign up to request clarification or add additional context in comments.

Comments

0

I have found that the correct "c" way of doing this is:

void __init(void) __attribute__ ((naked)) __attribute__ ((section (".init9")));
void __init(void)
{   
    asm volatile ("clr __zero_reg__");
    SP = RAMEND;   
    asm volatile ( "rjmp main");             
}

Where at the end, it jumps to your main function. This produces the following assembly output proposed by yumbrad:

// asm volatile ("clr __zero_reg__");
7800:   11 24           eor r1, r1

// SP = RAMEND;   
7802:   8f ef           ldi r24, 0xFF   ; 255
7804:   98 e0           ldi r25, 0x08   ; 8
7806:   9e bf           out 0x3e, r25   ; 62
7808:   8d bf           out 0x3d, r24   ; 61

// asm volatile ( "rjmp main");             
780a:   00 c0           rjmp    .+0         ; 0x780c <main>

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.