Stránka 1 z 4
C - offset položky ve struktuře
Napsal: 06 srp 2016, 08:58
od lesana87
Zdravím Bastlírnu.
Při pokusech s programováním v C jsem narazila na problém. Mám strukturu a potřebovala bych znát offset některé položky v té struktuře, tak abych ten offset mohla použít v inline assembleru. Překladač mám SDCC.
Struktura vypadá nějak takhle:
Kód: Vybrat vše
struct task_struct {
signed char state;
signed char counter;
char priority;
void * tstack; /* task stack */
int signal;
....
};
A já potřebuju offset položky tstack, abych se na ni mohla odkázat v:
Kód: Vybrat vše
__asm
....
xor A
....
ld IX,(#_current)
ld L,A
ld H,A
add HL,SP ; HL = puvodni SP
ld _tstack(IX),L ; Ulozi do current.tstack
ld _tstack+1(IX),H
....
__endasm
kde current je pointer na strukturu task_struct.
S tím _tstack to nefunguje, to linker zahlásí neznámý symbol.
Mohla bych to tam napsat na tvrdo, že to je 3, ale jde mi o to, aby to fungovalo, i když tu strukturu pozměním nebo když změním překladač a ten tu strukturu jinak zapakuje. Zkrátka aby to bylo přenositelné, když už se patlám s tím C.
Poradí prosím někdo, jak to udělat?
Edit: Našla jsem makro offsetof(s, m), ale nevím, jak ho s tím inline assemblerem použít.
![Sad :(](./images/smilies/icon_sad.gif)
Napsal: 06 srp 2016, 10:21
od berk
Zkrátka aby to bylo přenositelné, když už se patlám s tím C.
Aby to bylo přenositelné, tak bych se vyhnul tomu inline assembleru. Co je vlastně důvodem, že ho tam máš?
Makro je kus c-čka, které preprocessor rozbalí - to ten assembler asi nedá.
Já bych si na tu položku tstack udělal pointer a ten pak použil v tom assembleru.
Nebo
Pointer na tstack mínus pointer na strukturu je ten offset.
Napsal: 06 srp 2016, 11:47
od lesana87
Inline assembler tam mám proto, že potřebuju udělat něco, co to Cčko nedá. Konkrétně přepnout task a s ním i zásobník.
Hraní s pointerama je fajn, ale já potřebuju symbolickou konstantu, kterou mi ten assembler vezme. Takže třeba
je OK, ale jak tam nacpu nějaké pointery, už to nefunguje.
![Sad :(](./images/smilies/icon_sad.gif)
Napsal: 06 srp 2016, 12:22
od hakamusai
ten tstack (void * tstack; /* task stack */) je pointer na nějakou další strukturu ? nešlo by to do inline zapsat jako standard v cečku ?
Napsal: 06 srp 2016, 12:35
od frpr666
Já nevím, že všichni chtějí furt dokola kódovat v assembleru.
Podle mě je offsetof() vestavěná funkce podobně jako sizeof()
Pokud vezmu příklad shora, potom offsetof() použiju v programu a potom se podívám do výpisu .lst, tak by to mělo fungovat dle očekávání. "offsetof" člena struktury "signal" vrací 0x06.
Kód: Vybrat vše
129 ; src/helloworld.c:18: i = offsetof(struct task_struct, signal);
000000 7F 06 [12] 130 mov r7,#0x06
Kód: Vybrat vše
// file helloworld.c
#include <stddef.h>
struct task_struct
{
signed char state;
signed char counter;
char priority;
void * tstack; /* task stack */
int signal;
};
void main()
{
char i;
// test vestavene funkce offsetof
i = offsetof(struct task_struct, signal);
do
{
}
while(--i);
while(1);
}
//EOF
Napsal: 06 srp 2016, 12:43
od lesana87
hakamusai píše:ten tstack (void * tstack; /* task stack */) je pointer na nějakou další strukturu ? nešlo by to do inline zapsat jako standard v cečku ?
tstack je (jak je uvedeno) ukazatel na zásobník tasku.
Nevím, co je myšleno tím "inline standard v Cčku", je to zapsané jako inline v Cčku, jestli myslíš inline s parametrama jako je v GCC, tak to v SDCC není.
Napsal: 06 srp 2016, 12:49
od lesana87
frpr666 píše:Já nevím, že všichni chtějí furt dokola kódovat v assembleru.
Tak mi prosím ukaž, jak v C napíšeš tohle:
Kód: Vybrat vše
void switch_to(void * new) __z88dk_fastcall __naked
{
new;
__asm
push AF
push BC
ld BC,(#_current)
xor A
sbc HL,BC
jr z,00004$ ; new == current, neni co prepnout
add HL,BC ; Vrati HL
push DE
push IX
push IY
ld IX,(#_current)
ld (#_current),HL
push HL
pop IY
ld L,A
ld H,A
add HL,SP ; HL = puvodni SP
ld TSTACK(IX),L ; Ulozi do current.tstack
ld TSTACK+1(IX),H
ld L,TSTACK(IY)
ld H,TSTACK+1(IY) ; HL = new.tstack
ld SP,HL
pop IY
pop IX
pop DE
00004$: pop BC
pop AF
ret
__endasm;
}
![Confused :?](./images/smilies/icon_confused.gif)
Napsal: 06 srp 2016, 13:07
od frpr666
@Lesana Co to je, o jakém uprocesoru se tady bavíme?
Napsal: 06 srp 2016, 13:17
od lesana87
Operační systém pro Z80.
Napsal: 06 srp 2016, 13:36
od lesana87
Ano, SDCC zná offsetof(), psala jsem o tom hned v prvním příspěvku, že nevím, jak to dostat do toho assembleru.
Proč by nemohla Z80 multitaskovat?
Napsal: 06 srp 2016, 13:37
od frpr666
Není Z80 už tak trochu Retro? Kdo to vůbec vyrábí. Na jakém chipu to programuješ?
Napsal: 06 srp 2016, 13:43
od berk
Napsal: 06 srp 2016, 13:50
od lesana87
Retro je nějak zakázaný? Programuju to na PCčku, (po)běží to na Zilog Z84C0010 s externí MMU. Snažím se portovat Linux 0.12, ten je taky retro.
Ale šlo mi o ten offset a jak ho dostat do inline assembleru, nechci tu řešit co je nebo není retro.
![Sad :(](./images/smilies/icon_sad.gif)
Asi to holt pořeším jako Torvalds hláškama:
Kód: Vybrat vše
/* these are hardcoded - don't touch */
/* these are not to be changed without changing head.s etc */
Napsal: 06 srp 2016, 14:17
od frpr666
No dobrá, nemusíme říkat nahlas slovo Retro. Můžeme říct třeba Vintage.
A to jako opravdu na 8 bit. procesoru poběží operační systém Linux a bude něco dělat?
Kolik máš k dispozici RAM a FLASH ROM?
Napsal: 06 srp 2016, 14:30
od lesana87
Nevím, jestli poběží, snažím se.
Prozatím si vystačím se 128KB RAM a 32KB ROM, ale fyzický adresní prostor je 1MB. Každý task má k dispozici 64KB logický adresní prostor, ten je daný tou Z80kou.
Místo zatím problém není, problém je, že SDCC nemá ten inline assembler s parametrama jako má GCC a tak to musím všelijak obcházet.