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: 3296
Registrován: 20 zář 2014, 02: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: 107
Registrován: 07 úno 2014, 01: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: 3296
Registrován: 20 zář 2014, 02: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: 943
Registrován: 17 dub 2007, 02: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, 01: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: 3296
Registrován: 20 zář 2014, 02: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: 3296
Registrován: 20 zář 2014, 02: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, 01: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: 3296
Registrován: 20 zář 2014, 02:00

#9 Příspěvek od lesana87 »

Operační systém pro Z80.

Uživatelský avatar
lesana87
Příspěvky: 3296
Registrován: 20 zář 2014, 02: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, 01: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: 107
Registrován: 07 úno 2014, 01: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: 3296
Registrován: 20 zář 2014, 02: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, 01: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: 3296
Registrován: 20 zář 2014, 02: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ů“