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