logo elektroda
logo elektroda
X
logo elektroda
Adblock/uBlockOrigin/AdGuard mogą powodować znikanie niektórych postów z powodu nowej reguły.

[atmega16][c] Inicjalizacja stosu w asm

stasiu2323 22 Lut 2010 22:33 3702 6
  • #1 7736480
    stasiu2323
    Poziom 13  
    Witam.

    Chce zainicjować stos korzystając z makra RAMEND żeby nadawał się dla różnych procesorów.

    
    #include <avr/boot.h>
    
    
    static void __start(void) __attribute__ (( section( ".init2"), naked, used ));
    
    static void __start(void){
    	asm volatile (
    		"out __SP_L__, %A0" "\n\t"
    		"out __SP_H__, %B0" "\n\t"
    		"clr __zero_reg__" "\n\t"
    		"out __SREG__, __zero_reg__" "\n\t"
            : : "y"( ( uint16_t )( RAMEND ) ) );
    }
    
    void main(void) __attribute__ (( naked, used ));
    
    void main(void){
      asm("jmp 0");
    }
    
    


    Niestety po kompilacji kod wygląda tak.

    
    00001c00 <__start>:
    static void __start(void){
    /*  asm("clr __zero_reg__" "\n\t"
          "out __SREG__,__zero_reg__" "\n\t"
          "ldi r28,0x5f" "\n\t"
          "ldi r29,0x04" "\n\t);*/
            asm volatile (
        1c00:       2f e5           ldi     r18, 0x5F       ; 95
        1c02:       34 e0           ldi     r19, 0x04       ; 4
        1c04:       e9 01           movw    r28, r18
        1c06:       cd bf           out     0x3d, r28       ; 61
        1c08:       de bf           out     0x3e, r29       ; 62
        1c0a:       11 24           eor     r1, r1
        1c0c:       1f be           out     0x3f, r1        ; 63
    
    
    


    Opcje kompilacji
    
    avr-gcc -g -Os -mmcu=atmega16 -c boot.c
    avr-gcc -mmcu=atmega16 -nostartfiles -g  -Wl,--section-start=.text=0x1C00 -o boot.elf boot.o
    avr-objcopy -O ihex boot.elf boot.hex
    avr-objdump -h -S boot.elf > boot.lst
    


    Rozwiązałem ten problem w następujący sposób
    
    	asm volatile (
    		"out __SP_L__, %A0" "\n\t"
    		"out __SP_H__, %B0" "\n\t"
    		"clr __zero_reg__" "\n\t"
    		"out __SREG__, __zero_reg__" "\n\t"
    		"in r28, __SP_L__" "\n\t"
    		"in r29, __SP_H__" "\n\t"		
            : : "r"( ( uint16_t )( RAMEND ) ) );
    


    Interesuje mnie jak napisać kod korzystając z makra RAMEND które od razu uzupełni rejestr Y.

    Pozdrawiam
  • #4 7741595
    stasiu2323
    Poziom 13  
    Piszę bootloader aby pozbyć się tablicy wektorów ustawiłem flagę "-nostartfiles" która usuwa też kod inicjalizujący stos. Pytam w sumie z czystej ciekawości bo jak pisałem wyżej znalazłem obejście problemu.
  • Pomocny post
    #5 7743591
    zumek
    Poziom 39  
    stasiu2323 napisał:


    Interesuje mnie jak napisać kod korzystając z makra RAMEND które od razu uzupełni rejestr Y.


    No przecież już go napisałeś:
    
    static void __start(void){
       asm volatile (
          "out __SP_L__, %A0" "\n\t"
          "out __SP_H__, %B0" "\n\t"
          "clr __zero_reg__" "\n\t"
          "out __SREG__, __zero_reg__" "\n\t"
            : : "y"( ( uint16_t )( RAMEND ) ) );
    } 
    

    W wyniku otrzymałeś to:
    
        1c00:       2f e5           ldi     r18, 0x5F       ; 95
        1c02:       34 e0           ldi     r19, 0x04       ; 4
        1c04:       e9 01           movw    r28, r18
        1c06:       cd bf           out     0x3d, r28       ; 61
        1c08:       de bf           out     0x3e, r29       ; 62
        1c0a:       11 24           eor     r1, r1
        1c0c:       1f be           out     0x3f, r1        ; 63
    

    RAMEND masz załadowane do Y i SP
    I czego chcesz więcej :?:
  • #6 7744847
    rpal
    Poziom 27  
    w plikach nagłównowych obojetnie czy dla C czy dla asm masz zdefiniowane stałą RAMEND. W sytuacji kiedy definiujesz rodzaj procesora tym samym określasz plik nagłówkowy oraz stałą RAMEND. Zatem twoje pytanie to masło maślane.
  • #7 7755219
    stasiu2323
    Poziom 13  
    Fakt pomyliłem MOVW z MOV moje niedopatrzenie.
    Dzięki za pomoc.
    Pozdrawiam
REKLAMA