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

Błąd GCC przy wstawkach assemblera w funkcji delay w AVR Studio

ziggi86 02 Kwi 2008 19:25 1202 9
REKLAMA
  • #1 4985956
    ziggi86
    Poziom 13  
    Posty: 85
    Pomógł: 6
    Ocena: 6
    Witam

    Mam następujący problem...już drugie dzień się głowię i nic... Chciałem zrobić wstawki asseblerowskie w postaci funkcji delay w AVR Stuido. Całość napisałem na podstawie informacji zawartych w manualu do WinAvr. Wszystko według mnie wydaje się poprawnie napisane, program w assemblerze kompiluje się i nie zgłasza żadnych błędów, co do samej symulacji chodzi dokładnie tak jak tego chciałem :) jednak GCC cały czas wysypuje błąd:
    ../delay.c:28: error: invalid 'asm': operand number out of range

    sprawdziłem jeszcze raz czy rejestry są poprawnie dobrane do operandów i nie znalazłem żadnego błędu...

    Słyszałem że można jeszcze robić wstawki assemblerowskie w osobnym pliku i potem dodawać go do C w postaci funkcji.... aczkolwiek nie znalazłem nigdzie jak to się robi :)

    z góry dziękuje za wszelką pomoc

    poniżej fragment programu w C:



    
    #include <avr/pgmspace.h>
    
    void delayus8(uint8_t time)
    
    {
    				
    			asm volatile(
    					"\n" 
    					"ldi %r19,time" "\n\t"	
    		                 "delay_loop%=:" "\n\t"
    					"dec %r19"  "\n\t"		
    					"nop"	"\n\t"	
    					"nop"	"\n\t"		
    					"nop"	"\n\t"		
    					"nop"	"\n\t"		
    					"nop"	"\n\t"		
    					"nop"	"\n\t"		
    					"cpi %r19,0" "\n\t"	
    					"brne delay_loop%=" "\n\t"	
    					::"r"(time));
    																			// 10*125ns=1us
    
    					}
    
  • REKLAMA
  • #2 4986290
    MarasK
    Poziom 18  
    Posty: 231
    Pomógł: 19
    Ocena: 4
    to powinno dać Ci do myślenia:
    asm volatile("nop\n\t"
                 "nop\n\t"
                 "nop\n\t"
                 "nop\n\t"
                 ::);
    

    Przyjrzyj się gdzie są cudzysłowy :)
  • REKLAMA
  • REKLAMA
  • #4 4986393
    Freddie Chopin
    Specjalista - Mikrokontrolery
    Posty: 13336
    Pomógł: 1712
    Ocena: 870
    wypisywanie funkcji w assemblerze jest dosyc proste. jesli nie jestes w stanie znalezc tego w manualu do swojego kompilatora, to sciagnij ze strony microchipa manuala co kompilatora C30 - oparty jest on na gcc, wiec najprawdopodobniej bedzie sie to robilo tak samo.

    0x41 0x56 0x45!!
  • #5 4986601
    zumek
    Poziom 39  
    Posty: 3352
    Pomógł: 695
    Ocena: 52
    ziggi86 napisał:
    Mam następujący problem...
    
    					"ldi %r19,time" "\n\t"	
    

    Sprawdź proszę łaskawco , jakich argumentów potrzebuje LDI

    Piotrek
  • REKLAMA
  • #7 4987128
    ziggi86
    Poziom 13  
    Posty: 85
    Pomógł: 6
    Ocena: 6
    Cytat:
    Sprawdź proszę łaskawco , jakich argumentów potrzebuje LDI


    Według noty aplikacyjnej Atmlea :
    Syntax:LDI RD,K
    Operands:
    16≤r≤31, 0≤K≤255

    więc się zgadza wszystko... K ma być 8 bitowa wartością wpisana do rejestrów 16-31 :)

    A co do tych wstawek w innym pliku - póki co to dla mnie czarna magia ;) ale pewnie jak to zwykle okaże się że jest to bardzo proste.

    W każdym razie dzięki za zainteresowanie.


    Pozdr
  • Pomocny post
    #8 4987856
    zumek
    Poziom 39  
    Posty: 3352
    Pomógł: 695
    Ocena: 52
    ziggi86 napisał:
    ...więc się zgadza wszystko...

    Wprost przeciwnie - nic się nie zgadza :!:
    ziggi86 napisał:

    K ma być 8 bitowa wartością wpisana do rejestrów 16-31 :)

    No właśnie , a Ty jako argument K , podajesz time , który to jest adresem(wskaźnikiem) do komórki pamięci RAM i na dokładkę , ten adres w procesie kompilacji nie jest znany , bo time jest zmienną lokalną.
    Argument K , MUSI być konkretną liczbą , lub ... użyj innego rozkazu(ów).
    ziggi86 napisał:

    A co do tych wstawek w innym pliku - póki co to dla mnie czarna magia ;) ale pewnie jak to zwykle okaże się że jest to bardzo proste.

    Przeszukaj forum , bo na pewno była o tym "mowa".

    Piotrek
  • Pomocny post
    #9 4988065
    szelus
    Poziom 34  
    Posty: 1508
    Pomógł: 315
    Ocena: 53
    zumek napisał:
    ziggi86 napisał:
    ...więc się zgadza wszystko...

    Wprost przeciwnie - nic się nie zgadza :!:
    ziggi86 napisał:

    K ma być 8 bitowa wartością wpisana do rejestrów 16-31 :)

    No właśnie , a Ty jako argument K , podajesz time , który to jest adresem(wskaźnikiem) do komórki pamięci RAM i na dokładkę , ten adres w procesie kompilacji nie jest znany , bo time jest zmienną lokalną.
    Argument K , MUSI być konkretną liczbą , lub ... użyj innego rozkazu(ów).


    To też oczywiście, ale obstawiam, że chodzi o składnię asemblera w cudzysłowach. Tam znak % oznacza odwołanie do argumentu instrukcji asm, czyli:
    1. rejestry podaje się wprost - r19, nie %r19,
    2. %0, %1 itd. to odwołania do argumentu
    3. co to ma być "%=" ?

    Czyli np. zamiast tego "ldi %r19, time" trzeba by chyba napisać "mov r19, %0".

    Poza tym, należałoby poinformować kompilator, że kod asemblerowy modyfikuje r19 (po trzecim dwukropku).
  • #10 4989377
    ziggi86
    Poziom 13  
    Posty: 85
    Pomógł: 6
    Ocena: 6
    Witam

    Mieliście racje, błąd był w instrukcji LDI, choć wydawało mi się że gdy odwołuje się bezpośrednio to funkcji - to zawsze wstawiam jakąś wartość ... którą później ładuje do rejestru za pomocą LDI no ale okazało się to nie prawdą ;)


    Dzięki za pomoc :)

    Temat uważam za zamknięty.

    Pozdr

Podsumowanie tematu

✨ Problem dotyczył błędu kompilacji GCC w AVR Studio przy użyciu wstawek assemblera w funkcji delay. Kompilator zgłaszał błąd "invalid 'asm': operand number out of range" podczas próby użycia instrukcji LDI z argumentem będącym zmienną lokalną (time). Dyskusja wykazała, że instrukcja LDI wymaga stałej 8-bitowej wartości (operand K), a nie adresu zmiennej w pamięci RAM, co powodowało błąd. Poprawne użycie inline assemblera wymaga podawania rejestrów bez znaków procentowych oraz odpowiedniego formatowania składni w cudzysłowach. Zasugerowano także informowanie kompilatora o modyfikacji rejestrów w sekcji clobber. Ostatecznie problem rozwiązano przez korektę instrukcji LDI, zastępując niepoprawne odwołanie do zmiennej lokalnej stałą lub innym rozkazem. Wstawki assemblera w osobnym pliku również są możliwe, ale wymaga to innej metody integracji z kodem C.
Wygenerowane przez model językowy.
REKLAMA