MariuszC
Guest
Tue Nov 09, 2004 9:04 am
Witam,
czy da się jakoś zapisać kod w C, aby otrzymać liczbę dwubajtową
unsigned short z dwóch liczb unsigned char tak, aby kompilator
wygenerował jak najmniej kodu.
Np:
unsigned short wValue;
unsigned char byValue1, byValue2;
wValue = (byValue1<<

| byValue2;
albo
wValue = (byValue1<<

+ byValue2;
promują byValue1 oraz byValue2 do liczby unsigned short
potem je ORują ze sobą, a przecież wiadomo że byValue1
ma trafić na starszy bajt wValue, a byValue2 na młodszy
i to wszystko.
Są jakieś makra jak np:
HIBYTE(wValue) = byValue1;
LOBYTE(wValue) = byValue2;
dzięki którym kompilator by wpisywał wartość do odpowiedniego
rejestru, albo komórki pamięci? Ja nie znalazłem, albo przegapiłem
(jeśli w ogóle coś takiego istnieje). Może Ktoś z Was zna rozwiązanie.
Po prostu wkurza mnie, że zawsze brakuje FLASHa, a kompilator
dodatkowo generuje niepotrzebny kod, tymbardziej w takich prostych
przypadkach.
Mariusz
Piotr Chmiel
Guest
Tue Nov 09, 2004 10:11 am
On Tue, 9 Nov 2004, MariuszC wrote:
Quote:
Po prostu wkurza mnie, że zawsze brakuje FLASHa, a kompilator
dodatkowo generuje niepotrzebny kod, tymbardziej w takich prostych
przypadkach.
A ile go masz że Ci ciągle brakuje ?
Dostosuj AVR do swoich potrzeb
Andrzej Ekiert
Guest
Tue Nov 09, 2004 10:19 am
MariuszC wrote:
Quote:
czy da się jakoś zapisać kod w C, aby otrzymać liczbę dwubajtową
unsigned short z dwóch liczb unsigned char tak, aby kompilator
wygenerował jak najmniej kodu.
Np:
unsigned short wValue;
unsigned char byValue1, byValue2;
wValue = (byValue1<<

| byValue2;
albo
wValue = (byValue1<<

+ byValue2;
Nie używam co prawda AVRów, ale na taki sam problem pod gcc na procesory
dsPIC Microchipa, oraz pod mcc18 na PIC18 rozwiązałem w sposób następujący:
/*
* Use when assigning to unsigned 8-bit variable
* (x is a 16 bit variable)
*/
#define HIGH_BYTE(x) (*(unsigned char*)((unsigned char*)(&x)+1))
#define LOW_BYTE(x) (*(unsigned char*)((unsigned char*)(&x)))
Paskudne to to jest, wiem.
hth,
--
Andrzej Ekiert
Polskie Forum Microchipa
http://www.ekiert.com/microchip
Marek Dzwonnik
Guest
Tue Nov 09, 2004 11:19 am
Użytkownik "Andrzej Ekiert" <reply@to.invalid> napisał w wiadomości
news:cmq5j2$jpv$1@polsl.gliwice.pl
Quote:
czy da się jakoś zapisać kod w C, aby otrzymać liczbę dwubajtową
unsigned short z dwóch liczb unsigned char tak, aby kompilator
wygenerował jak najmniej kodu.
Np:
wValue = (byValue1<<

| byValue2;
albo
wValue = (byValue1<<

+ byValue2;
dsPIC Microchipa, oraz pod mcc18 na PIC18 rozwiązałem w
sposób następujący:
#define HIGH_BYTE(x) (*(unsigned char*)((unsigned char*)(&x)+1))
#define LOW_BYTE(x) (*(unsigned char*)((unsigned char*)(&x)))
A może z wykorzystaniem unii zawierajacej alternatywnie jednego int-a albo
strukture zlozona z dwoch bajtów? To wprawdzie nie jest zbyt legalne, ale
powinno działać:
union {
struct {
unsigned char b1;
unsigned char b2;
} asByte;
unsigned int asWord;
} value;
value.asWord
value.asByte.b1
value.asByte.b2
--
Marek Dzwonnik, GG: #2061027 - zwykle jako 'niewidoczny'
(Uwaga Gadu-Gadulcowicze: Nie odpowiadam na anonimy.)
J.F.
Guest
Tue Nov 09, 2004 11:49 am
On Tue, 09 Nov 2004 11:19:13 +0100, Andrzej Ekiert wrote:
Quote:
czy da się jakoś zapisać kod w C, aby otrzymać liczbę dwubajtową
unsigned short z dwóch liczb unsigned char tak, aby kompilator
wygenerował jak najmniej kodu.
wValue = (byValue1<<

| byValue2;
albo
wValue = (byValue1<<

+ byValue2;
#define HIGH_BYTE(x) (*(unsigned char*)((unsigned char*)(&x)+1))
#define LOW_BYTE(x) (*(unsigned char*)((unsigned char*)(&x)))
Paskudne to to jest, wiem.
Paskudne. Bo sie okaze na innym procku [np AVR] zmienna jest w jednym
z [np 32] rejestrow i nie ma adresu :-)
Chyba lepiej to pierwsze i zdac sie na optymalizator.
J.
Albert Bartoszko
Guest
Tue Nov 09, 2004 2:16 pm
Użytkownik J.F. napisał:
[...]
Quote:
#define HIGH_BYTE(x) (*(unsigned char*)((unsigned char*)(&x)+1))
#define LOW_BYTE(x) (*(unsigned char*)((unsigned char*)(&x)))
Paskudne to to jest, wiem.
Paskudne. Bo sie okaze na innym procku [np AVR] zmienna jest w jednym
z [np 32] rejestrow i nie ma adresu
Nie, po użyciu czegoś takiego już nie będzie w rejestrze i będzie miała
adres.
Quote:
Chyba lepiej to pierwsze i zdac sie na optymalizator.
Jak ktoś jest tak oszczędny to jednak proponowałbym asembler
Albert
MariuszC
Guest
Tue Nov 09, 2004 2:47 pm
Marek Dzwonnik wrote:
Quote:
Użytkownik "Andrzej Ekiert" <reply@to.invalid> napisał w wiadomości
news:cmq5j2$jpv$1@polsl.gliwice.pl
czy da się jakoś zapisać kod w C, aby otrzymać liczbę dwubajtową
unsigned short z dwóch liczb unsigned char tak, aby kompilator
wygenerował jak najmniej kodu.
Np:
wValue = (byValue1<<

| byValue2;
albo
wValue = (byValue1<<

+ byValue2;
dsPIC Microchipa, oraz pod mcc18 na PIC18 rozwiązałem w
sposób następujący:
#define HIGH_BYTE(x) (*(unsigned char*)((unsigned char*)(&x)+1))
#define LOW_BYTE(x) (*(unsigned char*)((unsigned char*)(&x)))
A może z wykorzystaniem unii zawierajacej alternatywnie jednego int-a albo
strukture zlozona z dwoch bajtów? To wprawdzie nie jest zbyt legalne, ale
powinno działać:
union {
struct {
unsigned char b1;
unsigned char b2;
} asByte;
unsigned int asWord;
} value;
value.asWord
value.asByte.b1
value.asByte.b2
Też to ćwiczyłem i jest znacznie lepiej, jednak np
po przeniesieniu części kodu na 51 trzeba będzie pamiętać
że one chyba (dawno nic w nich nie robiłem) mają
odwrotny zapis MSB,LSB, a nie jak w AVR LSB,MSB
Mariusz
Mister
Guest
Tue Nov 09, 2004 3:20 pm
Quote:
po przeniesieniu części kodu na 51 trzeba będzie pamiętać
że one chyba (dawno nic w nich nie robiłem) mają
odwrotny zapis MSB,LSB, a nie jak w AVR LSB,MSB
Tak jest. I to jest denerwujące.
Mister
Marek Dzwonnik
Guest
Tue Nov 09, 2004 4:32 pm
Użytkownik "Mister" <wojpie@wywal_to.poczta.onet.pl> napisał w
wiadomości news:cmqn9j$dmd$1@atlantis.news.tpi.pl
Quote:
po przeniesieniu części kodu na 51 trzeba będzie pamiętać
że one chyba (dawno nic w nich nie robiłem) mają
odwrotny zapis MSB,LSB, a nie jak w AVR LSB,MSB
Tak jest. I to jest denerwujące.
W takim razie zależnie od typu procesora zdefiniować:
#define MSB b1
#define LSB b2
lub na odwrót
#define MSB b2
#define LSB b1
i odwoływać się do pól struktury przez MSB i LSB.
value.asByte.MSB
value.asByte.LSB
--
MDz
Jurek Szczesiul
Guest
Tue Nov 09, 2004 4:37 pm
Tue, 09 Nov 2004 10:04:38 +0100, na pl.misc.elektronika, MariuszC
napisał(a):
Quote:
czy da się jakoś zapisać kod w C, aby otrzymać liczbę dwubajtową
unsigned short z dwóch liczb unsigned char tak, aby kompilator
wygenerował jak najmniej kodu.
Cześć.
memcpy((char*)&word,(char*)&chr2,1);
64: 00 91 62 00 lds r16, 0x0062
68: 00 93 74 00 sts 0x0074, r16
memcpy((char*)&word+1,(char*)&chr1,1);
6c: 10 91 63 00 lds r17, 0x0063
70: 10 93 75 00 sts 0x0075, r17
--
Pozdrowienia
Jurek Szczesiul
J.F.
Guest
Tue Nov 09, 2004 5:13 pm
On Tue, 9 Nov 2004 17:37:06 +0100, Jurek Szczesiul wrote:
Quote:
memcpy((char*)&word,(char*)&chr2,1);
64: 00 91 62 00 lds r16, 0x0062
68: 00 93 74 00 sts 0x0074, r16
memcpy((char*)&word+1,(char*)&chr1,1);
6c: 10 91 63 00 lds r17, 0x0063
70: 10 93 75 00 sts 0x0075, r17
Eeeee .. czy on ma prawo tak robic ?
powinien wywolac funkcje biblioteczna memcpy.
J.
Marcin Stanisz
Guest
Tue Nov 09, 2004 6:00 pm
Quote:
Eeeee .. czy on ma prawo tak robic ?
powinien wywolac funkcje biblioteczna memcpy.
I to jest dopiero optymalizacja! ;-)
Pozdrawiam
Marcin Stanisz
--
Wysłano z serwisu OnetNiusy:
http://niusy.onet.pl
Marek Michalkiewicz
Guest
Tue Nov 09, 2004 9:45 pm
J.F. <jfox_nospam@poczta.onet.pl> wrote:
Quote:
Eeeee .. czy on ma prawo tak robic ?
powinien wywolac funkcje biblioteczna memcpy.
Ma prawo. GCC (na kazda architekture, niekoniecznie AVR) ma troche
funkcji wbudowanych - zamiast wywolania funkcji moze wygenerowac
kawalek kodu, robiacy to samo tylko bardziej efektywnie. Mozna
uzyc -fno-builtin (lub dla konkretnej funkcji: -fno-builtin-memcpy)
by te optymalizacje wylaczyc.
Wstawienie kawalka kodu ma te przewage nad wywolaniem funkcji, ze
nie "zapomina" sie tylu rejestrow (AVR: r18-r27 i r30-r31), wiec
moze sie oplacac nawet dla funkcji nieco wiekszych niz memcpy().
Marek