Predavani hodnot mezi asm a C v CCS 550
Josef Štengl
ok1ced na nagano.cz
Čtvrtek Leden 22 22:34:59 CET 2015
No, vrtalo mi to hlavou, tak jsem si to ověřoval, a než jsem se pokorně omluvil za mystifikaci tak jste byl rychlejší. Mám
zafixováno nepoužívat, ale už jsem zapomněl proč. Omlouvám se.
Osobně proměnné v inline asm nepoužívám protože:
- nejsem na to zvyknutý (5 let jsem se živil programování v ASIL D a nějak to na mě zanechalo následky)
- nevím co to udělá s obsahem registrů a nehodlám to studovat extra pro každý překladač (to je například ta poznámka, co
jste psal)
- přestal jsem nad tím uvažovat, po té, co jsem četl v jednom manuálu, že __asm na začátku funkce neukládá do stacku
použité proměnné a musí to být zajištěno manuálně. Hezký, ale to s to raději napíši v asm celé.
napsal bych si krátký prográmek v asm
.arm
.ref bla
; prototyp v C: extern uint32_t change_mrc_asm(void);
.def change_mrc_asm
.asmfunc
change_mrc_asm
; uložení cpu módu
svc #0x70000 ; změní mód na supervizor a a pokud zůstane to, tak to skočí na následující řádku (přesvědčíte se v
debuggeru, spodní řádek). Pak je třeba se vrátit do původního módu.
mrc p15, #0, r0, c12, c0, #0 ; mrc je read, nevím co to přesně znamená
; cps #16 ; switch to user mode, nebo jak je to tam dělané?
bx lr
.endasmfunc
V C pak zavolám:
bla = change_mrc_asm();
a pak se vrátit zpět do původního módu. Ale nevím jak je to koncipováno, musel bych vidět SWI obsluhu.
Dne 22.1.2015 v 21:38 Pavel Hudeček napsal(a):
> Obsluha swi (kterou nemůžu změnit, neboť je součástí jakési lib, od které nemám zdrojáky) dělá toto: Pokud je parametr
> 458752, zapne privilegovaný režim. Pak je možno např. použít MRC p15.
>
> Nakonec jsem našel i manuál jménem spnu151j a v něm je toto:
>
> Do not change the value of a C/C++ variable when using an asm statement. This is
> because the compiler does not verify such statements. They are inserted as is into the
> assembly code, and potentially can cause problems if you are not sure of their effect
>
> Chápu-li to správně, požadovanou věc provést lze, ale autor manuálu to nedoporučuje.
> Ale pořád nevím jak. Navíc se vůbec nezmiňují o opačné cestě, tedy použití hodnoty z proměnné v inline asm, s čímž by
> tento problém být neměl.
>
> PH
>
> Od: Josef Štengl <ok1ced na nagano.cz>
>
> Ehm, nedorozumění. Vy jste chtěl asm v C a já to pochopil jako mezi C a ASM zdrojovým souborem.
> To nejde. Viz manuál ke kompilátoru C. Předávání proměnných nepodporuje. Tedy jestli se za poslední rok nic nezměnilo.
>
> Je třeba to uďát jako ASM funkci a parametr je možno v SVC přerušení
> a) přečíst z proměnné (rychlejší a nezávislé na ARM/THUMB2 a endianitě
> b) přečíst instrukci svc v svc přerušení a bude to v armu, páč se to číslo do thumb2 nevejde.
>
> A není mi jasné, proč do swi cpete tak velké číslo, když ho nečtete. Ale na vysvětlení netrvám, je to jen poznámka.
>
> Jen mimochodem, je lepší psát __asm(...) místo asm(...). Ale to je věc jazykového purizmu, na funkci živočicháře to
> nemá vliv.
>
> Dne 22.1.2015 v 20:34 Pavel Hudeček napsal(a):
> > Odhad byl správný, jedná se o arm, konkrétně AM3358.
> > Překladač Ti v5.1.1
> > K výsledku to zatím nevede:
> >
> > . asm(" .ref ble\n"
> > . " ldr r1,ble\n"
> > . " swi #458752\n"
> > . " mrc p15, #0, r0, c12, c0, #0\n"
> > . " str [r1], r0\n"
> > . );
> >
> > [W0000]
> > Defined symbol 'ble' cannot have a .ref
> > .ref ble
> >
> > [E0001]
> > Address must be defined in the current section
> > ldr r1,ble
> >
> > [E0004]
> > Illegal operand
> > ldr r1,ble
> >
> > [E0005]
> > Missing operand(s)
> > str [r1], r0
> >
> > ble je globální proměnná typu uint32_t. Když jsem ji ještě navíc udělal static, zmizel první warning, ale zbytek
> zůstal.
> > Lokální static i nestatic též jen s errory.
> >
> > Od: Josef Štengl <ok1ced na nagano.cz>
> > Správně se zeptat :-)
> > 1) Cílová platforma/procesor (lépe platforma, než označení čipu)
> > 2) Překladač který používáte - asm zápisy se různí.
> >
> > Pak si najít manuál k překladači. A je - li to Texas, tak popis assembleru bude v jiném manuálu.
> >
> > Jinak je to věštění z křišťálové koule (bohužel nemám žádnou funkční ;-).
> >
> >
> > Z hlavy střelím jen možnost pro ARM a ti překladač. Ale vzhledem k tomu, že pojem ctg mi nic neříká, tak to můžete být
> > třeba pro C6000, což neznám (jen trochu C2000, mršku jednu proradnou):
> >
> > .ref n
> > ldr r1, n ; adresa do r1
> > ldr r0, [r1] ; hodnota do r0
> >
> > opačně
> > ldr r1, n ; adresa do r1
> > str r0, [r1] ; hodnota z r0 do n
> >
> > Dne 22.1.2015 v 15:28 Pavel Hudeček napsal(a):
> > > mám proměnnou n, která obsahuje 32b unsigned int a chtěl bych ji dostat do registru r0. Jindy zas potřebuji opačný
> > přenos.
> > >
> > > Při gůglení jsem našel, že by to v gcc mělo jít takto: mov r0,n. Jenže tak to nejde, takže se tu asi používá jiný
> > > překladač. (některé věci ze starterwaru mají dvě verze, jednu v adresáři gcc, druhou v cgt. Pokud první obsahuje
> > asm, tak
> > > mi obvykle nejde přeložit)
> > >
> > > Jak to tedy správně dělat? / Jak se správně ptát?
>
>
>
> _______________________________________________
> HW-list mailing list - sponsored by www.HW.cz
> Hw-list na list.hw.cz
> http://list.hw.cz/mailman/listinfo/hw-list
>
Další informace o konferenci Hw-list