C _ jak rozepsat ?__ádek

Miroslav Mraz mraz na seznam.cz
Neděle Duben 28 17:14:30 CEST 2013


Faktem je, že jsem se tomu memcpy() z newlib koukal trochu pod sukně a
vypadá to, že s nezarovnaným přístupem počítá a zřejmě i optimalizuje
počet cyklů právě podle toho zarovnání. A hlavně funguje i s tou lichou
adresou. Po vašem upozornění jsem to ale stejně předělal a používám svou
vlastní funkci, která dělá prostou bytovou kopii:

  25:../protokol.h **** /// memcpy s malou úpravou (pro firmware)
  26:../protokol.h **** static inline uint32_t nmemcpy (void* dst, const
void* src, uint32_t len) {
  28 0000 10B5     		push	{r4, lr}
  27:../protokol.h ****   register uint32_t i;
  28:../protokol.h ****   uint8_t* d = (uint8_t*) dst;
  29:../protokol.h ****   uint8_t* s = (uint8_t*) src;
  30:../protokol.h ****   for (i=0; i<len; i++) d[i] = s[i];
  34 0002 0023     		mov	r3, #0
  35 0004 02E0     		b	.L2
  37              	.L3:
  39 0006 CC5C     		ldrb	r4, [r1, r3]
  40 0008 C454     		strb	r4, [r0, r3]
  41 000a 0133     		add	r3, r3, #1
  43              	.L2:
  45 000c 9342     		cmp	r3, r2
  46 000e FAD1     		bne	.L3
  31:../protokol.h ****   return len;
  32:../protokol.h **** }
  48 0010 181C     		mov	r0, r3
  51 0012 10BD     		pop	{r4, pc}

To vypadá, že bude bez problémů, řekl bych, že takovéto přetypování bude
bezpečné, je to hezky čitelné. LDRB a STRB zřejmě lichou adresu zkousne.
Zase tak velké bloky dat se tam nepřenášejí a je na to čas. Ten váš
postup s násobením (resp. shiftem) a skládáním je správnější, protože
řeší i endienitu, ale mě se zde nehodí (dst může být ve skutečnosti
pointer na nějakou strukturu definovanou protokolem) a nejsem zrovna
purista, přenášet to na BE nebudu (není to kde vyzkoušet).
Moc díky za připomínky.

To s tím nečtením návodů berte spíš jako vtip. Ale spousta známých se
tím fakt řídí. Jinak jsem se za své poměrně dlouhé praxe s problémy
záhadných chyb v programu moc nesetkal. Buď mám kliku nebo spíš nějaký
blíže nedefinovatelný záhadný cit pro potenciální problémy. Více byly
problémy ze začátku, kdy to člověk mastil v assembleru v jednom souboru
a neměl zas tak moc zkušeností. V Céčku snad jen jednou, kdy protějšek
psal kolega a chodily mě od něj záhadná data v hlavičkách paketů. Blbě
jsme se domluvili a on používal nepakovanou strukturu a já pakovanou.

Časem si člověk vypracuje určitý styl psaní, který mu vyhovuje a má ho
vyzkoušený, že na dané platformě funguje. No a pak se objeví nová
platforma, kde to už může způsobit problém jako v tomto případě. Pak je
potřeba vyloupnout jádro problému a pak styl psaní programu přizpůsobit
- jak doporučuje wek, nebo vytvořit nějaký obal, který by umožňoval
použít stejný styl i zde. No a protože návyky se těžko mění, dal jsem se
touto, možná špatnou cestou.

Mrazík


Jan Waclawek píše v Ne 28. 04. 2013 v 13:27 +0200:

> To tiez nie je spravne; memcpy() s nezarovnanym pointrom moze a nemusi fungovat. Napriklad v Keili nefunguje, a je to podla normy uplne spravne. Problem je uz totiz v tom nezarovnanom pointri.
> 
> Ved som Vam napisal, ako je to spravne (skladat pomocou nasobenia a scitania), tak preco sa storcujete?
> 

> wek




Další informace o konferenci Hw-list