C - offset položky ve struktuře

Diskuze a poradna o programátorech a programování různých obvodů

Moderátor: Moderátoři

Zpráva
Autor
Uživatelský avatar
lesana87
Příspěvky: 4397
Registrován: 20 zář 2014, 00:00

C - offset položky ve struktuře

#1 Příspěvek 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. :(
Uživatelský avatar
berk
Příspěvky: 109
Registrován: 07 úno 2014, 00:00

#2 Příspěvek 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.
Uživatelský avatar
lesana87
Příspěvky: 4397
Registrován: 20 zář 2014, 00:00

#3 Příspěvek 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

Kód: Vybrat vše

#define TSTACK 3

je OK, ale jak tam nacpu nějaké pointery, už to nefunguje. :(
hakamusai
Příspěvky: 939
Registrován: 17 dub 2007, 00:00

#4 Příspěvek 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 ?
Uživatelský avatar
frpr666
Příspěvky: 1051
Registrován: 28 pro 2009, 00:00

#5 Příspěvek 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
Uživatelský avatar
lesana87
Příspěvky: 4397
Registrován: 20 zář 2014, 00:00

#6 Příspěvek 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í.
Uživatelský avatar
lesana87
Příspěvky: 4397
Registrován: 20 zář 2014, 00:00

#7 Příspěvek 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;
}

:?
Uživatelský avatar
frpr666
Příspěvky: 1051
Registrován: 28 pro 2009, 00:00

#8 Příspěvek od frpr666 »

@Lesana Co to je, o jakém uprocesoru se tady bavíme?
Uživatelský avatar
lesana87
Příspěvky: 4397
Registrován: 20 zář 2014, 00:00

#9 Příspěvek od lesana87 »

Operační systém pro Z80.
Uživatelský avatar
lesana87
Příspěvky: 4397
Registrován: 20 zář 2014, 00:00

#10 Příspěvek 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?
Uživatelský avatar
frpr666
Příspěvky: 1051
Registrován: 28 pro 2009, 00:00

#11 Příspěvek od frpr666 »

Není Z80 už tak trochu Retro? Kdo to vůbec vyrábí. Na jakém chipu to programuješ?
Uživatelský avatar
berk
Příspěvky: 109
Registrován: 07 úno 2014, 00:00

#12 Příspěvek od berk »

Operační systém pro Z80.


Něco jako FUZIX?
https://plus.google.com/+AlanCoxLinux/posts/a2jAP7Pz1gj
Uživatelský avatar
lesana87
Příspěvky: 4397
Registrován: 20 zář 2014, 00:00

#13 Příspěvek 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. :(
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 */
Uživatelský avatar
frpr666
Příspěvky: 1051
Registrován: 28 pro 2009, 00:00

#14 Příspěvek 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?
Uživatelský avatar
lesana87
Příspěvky: 4397
Registrován: 20 zář 2014, 00:00

#15 Příspěvek 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.
Odpovědět

Zpět na „Programování PIC, ATMEL, EEPROM a dalších obvodů“