Internet Info, s.r.o. Lupa Měšec Podnikatel Root Zdroják DigiZone Slunečnice Vitalia TopDrive KupDnes Navrcholu NovýTarif Dobrý web Weblogy Woko Jagg Computer.cz SK: MojeLinky

Hlavní navigace

Názory k článku
Anatomie grafického formátu PNG

Jet
Jet (neregistrovaný)
14. 9. 2006 10:08 Nový

big endian?

celé vlákno
big endian, tj. byte s nejvyšší váhou je v souboru na prvním místě

tohle je podle me LITTLE ENDIAN (konci malym bytem)
nebo se pletu?
LK
LK (neregistrovaný)
14. 9. 2006 10:13 Nový

Re: big endian?

celé vlákno
Pavel Tišnovský aura:98
14. 9. 2006 10:26 Nový

Re: big endian?

celé vlákno
Dost casto se to plete, ale jedna se opravdu o big endian.

Mimochodem, jaka je nejkratsi sekvence instrukci pro prohozeni bytu little endian-big endian v instrukcni sade x86?
Ondrej Ivanič
14. 9. 2006 10:58 Nový

Re: big endian?

celé vlákno
da sa nieco kratsie ako je bswap? (2 bajty)
Pavel Tišnovský aura:98
14. 9. 2006 11:27 Nový

Re: big endian?

celé vlákno
Dneska uz asi ne, ale na 486 se bswap protahl az na tri cykly (a v sestnactibitovem kodu na tri byty).

Ja jen, ze mi nekteri lide stale tvrdi, jak je slozite prevest little/big endian. Pravda, v takovem cecku to je zdlouhave a vysledny kod otresny, ale to pouze znamena, ze assembler je pro nektere veci vice semanticky vybaveny, nez ostatni jazyky :-)
Stanislav Brabec aura:91
14. 9. 2006 13:18 Nový

Re: big endian?

celé vlákno
A proto glibc definuje vše potřebné:

#include <byteswap.h>
...
x=bswap_16(x)
...
Pavel Tišnovský aura:98
14. 9. 2006 13:32 Nový

Re: big endian?

celé vlákno
Spis to bude funkce bswap_32(), ale stejne to primo neodpovida instrukci bswap na i86. Ta instrukce totiz meni data primo v jednom registru, kdezto bswap_16() a bswap_32() je univerzalnejsi (a tim padem obecne slozitejsi - pravdepodobne zabere vice registru, a to je na i86 dost problem).
...
... (neregistrovaný)
14. 9. 2006 14:18 Nový

Re: big endian?

celé vlákno

Ne, opravdu to umí použít instrukci bswap. Ale standardní funkce to není.

        x = bswap_32(x);
  400470:       0f cf                   bswap  %edi
        return x;
}
  400472:       89 f8                   mov    %edi,%eax
  400474:       c3                      retq   
...
... (neregistrovaný)
14. 9. 2006 14:45 Nový

Re: big endian?

celé vlákno

Ale zdá se, že standardní ntohl funguje stejně dobře.

        x = ntohl(x);
  400468:       89 f8                   mov    %edi,%eax
  40046a:       0f c8                   bswap  %eax
        return x;
}
  40046c:       c3                      retq   
Pavel Tišnovský aura:98
14. 9. 2006 15:22 Nový

Re: big endian?

celé vlákno
Porad se to moc podoba klasicke ceckovske funkci - proc to napriklad meni hodnoty hned dvou registru?
...
... (neregistrovaný)
14. 9. 2006 15:49 Nový

Re: big endian?

celé vlákno

To jen kvůli tomu, že vstup už byl v EDI a návratovou hodnotu bylo potřeba dát do EAX.

0000000000400470 <main>:

int main(int argc, char *argv[])
{
        uint32_t x = argc;
        x = ntohl(x);
  400470:       0f cf                   bswap  %edi
        return x;
}
  400472:       89 f8                   mov    %edi,%eax
  400474:       c3                      retq

Jinak u mne na systému to vypadá nějak takhle:

#define bswap_32(x) __bswap_32 (x)
...
#   define ntohl(x)     __bswap_32 (x)
...
/* Swap bytes in 32 bit value.  */
#define __bswap_constant_32(x) \
     ((((x) & 0xff000000) >> 24) | (((x) & 0x00ff0000) >>  8) |                   \
      (((x) & 0x0000ff00) <<  8) | (((x) & 0x000000ff) << 24))

#if defined __GNUC__ && __GNUC__ >= 2
# if __WORDSIZE == 64 || (defined __i486__ || defined __pentium__             \
                          || defined __pentiumpro__ || defined __pentium4__   \
                          || defined __k8__ || defined __athlon__             \
                          || defined __k6__)
/* To swap the bytes in a word the i486 processors and up provide the
   `bswap' opcode.  On i386 we have to use three instructions.  */
#  define __bswap_32(x) \
     (__extension__                                                           \
      ({ register unsigned int __v, __x = (x);                                \
         if (__builtin_constant_p (__x))                                      \
           __v = __bswap_constant_32 (__x);                                   \
         else                                                                 \
           __asm__ ("bswap %0" : "=r" (__v) : "0" (__x));                     \
         __v; }))
# else
#  define __bswap_32(x)                                                       \
     (__extension__                                                           \
      ({ register unsigned int __v, __x = (x);                                \
         if (__builtin_constant_p (__x))                                      \
           __v = __bswap_constant_32 (__x);                                   \
         else                                                                 \
           __asm__ ("rorw $8, %w0;"                                           \
                    "rorl $16, %0;"                                           \
                    "rorw $8, %w0"                                            \
                    : "=r" (__v)                                              \
                    : "0" (__x)                                               \
                    : "cc");                                                  \
         __v; }))
# endif
#else
# define __bswap_32(x) \
     (__extension__                                                           \
      ({ register unsigned int __x = (x); __bswap_constant_32 (__x); }))
#endif
Pavel Tišnovský aura:98
14. 9. 2006 15:59 Nový

Re: big endian?

celé vlákno
Aha, takze argc se predava v EDI a navratova hodnota z main se ocekava v EAX. Pak je to OK :-) (ja jsem mel pocit, ze to movuje kvuli tomu, ze vysledek dava - jako ceckovska funkce - vzdycky do EAX).
...
... (neregistrovaný)
14. 9. 2006 16:34 Nový

Re: big endian?

celé vlákno

Lepší příklad (a současně i ukázka jedné nevýhody takovéhoto způsobu optimalizace :-):

        x = ntohl(htonl(x));
  400470:       0f cf                   bswap  %edi
  400472:       0f cf                   bswap  %edi
        return x;
}
  400474:       89 f8                   mov    %edi,%eax
  400476:       c3                      retq   
Pavel Tišnovský aura:98
14. 9. 2006 16:37 Nový

Re: big endian?

celé vlákno
Nojo, to se neda nic delat. Vzhledem k tomu, ze se jedna vlastne o dve makra (a ne konstrukci jazyka), tak nema prekladac sanci zjistit, ze vlastne nemusi vubec nic generovat :-) Ale osobne bych na konec stejne vrazil spis xchg, je to o bajt kratsi.
...
... (neregistrovaný)
14. 9. 2006 17:17 Nový

Re: big endian?

celé vlákno
Já bych tam nechal ten mov. :-) xchg se na PPro+ rozkládá na tři mikroinstrukce, mov jen na jednu, navíc nezávisí na hodnotě toho druhého registru. Ale na tyhle optimalizace tu jsou odborníci jiní. :-)
Pavel Tišnovský aura:98
14. 9. 2006 17:22 Nový

Re: big endian?

celé vlákno
No, je pravda, ze uz pred casem jsem priznal, ze od Pentii II a vys uz na optimalizaci strojaku nemam :-) Takze ten xchg platil pro 486/PI, dal si nejsem jisty a radsi uz mlcim... :-)
uživatel si přál zůstat v anonymitě
14. 9. 2006 14:26 Nový

Re: big endian?

celé vlákno
* glibc možná, ale standard c99 se převodem nezabývá - jde tedy o nestandardní řešení

* funkci nelze implementovat s týmiž vlastnostmi (optimálnost) bez opuštění prostředků jazyka c (hádám, že jde o implementavi v assembleru).
Michal Kubeček
Michal Kubeček (neregistrovaný)
16. 9. 2006 11:10 Nový

Re: big endian?

celé vlákno
Standardní C se tím ani zabývat nemůže, protože reprezentaci čísel v paměti řeší velmi obecně, vlastně ani nepředpokládá, že byte má obvyklých 8 bitů.
ii
ii (neregistrovaný)
14. 9. 2006 12:04 Nový

Re: big endian?

celé vlákno
podla mna je najjednoduchsie si uvedomit nie ci ide msbyte k lsbyte zlava doprava ale ci od nizsej adresy k vyssej - pri vizualizacii plnenia suboru sa to fakt pletie ;)
Peter Ambrož
16. 9. 2006 19:02 Nový

Klobuk dole

celé vlákno
Dakujem autorovi za clanok "k veci". A po dlhom case aj diskusia "k veci" namiesto klasickeho flame.
aspergill
aspergill (neregistrovaný)
17. 9. 2006 10:06 Nový

Přiznám se,

celé vlákno
nerozumím konstrukci toho kontrolního polynomu. Co se dosazuje za x?
--==[FReeZ]==--
--==[FReeZ]==-- (neregistrovaný)
18. 9. 2006 1:44 Nový

Re: Přiznám se,

celé vlákno
x je libovolne 32bitove cislo, protoze edi je 32bitovy registr =) // funce prevadi pravdepodobne mezi big endian a little endian (to je jedna instrukce) a pak vysledek vrati (to je druha instrukce)
Pavel Tišnovský aura:98
18. 9. 2006 9:29 Nový

Re: Přiznám se,

celé vlákno
CRC je vlastne rozsireni puvodniho paritniho bitu, ktery je stale jeste pouzivan u nekterych typu pameti. K datum, tj. skupinam bytu je prirazena dalsi hodnota, u dnes pouzivanych CRC typicky o delce 32 bitu (4 byty). Tato hodnota odpovida zbytku po deleni danym polynomem nad telesem (0,1,+) - tj. scitani se provadi "modulo 2", jinymi slovy se jedna o operaci XOR. To je ovsem teorie (pomerne slozita, ale da se tak dva dny pred zkouskou pochopit :-)), v praxi k zadnemu deleni nedochazi, pouze se provadi operace nad posuvnym registrem, tj. vystacime s s operacemi ^, >> a << (xor a obe rotace). Mimochodem, ten polynom zvoleny u PNG je pro detekci chyb dost nevhodny, ale o tom si vice rekneme v dalsich pokracovanich tohoto seriulu.

Vice info viz http://www.w3.org/TR/PNG/#D-CRCAppendix (implementace CRC v cecku) a http://en.wikipedia.org/wiki/Cyclic_redundancy_check (obecne informace o CRC)
zigi
zigi (neregistrovaný)
25. 10. 2007 22:50 Nový

OT: Způsob pojmenování chunků

celé vlákno
(2×26)^5 = 380 204 032 neni to trochu moc .. nemelo by to spis byt jen: (26 {mala} + 26 {velka})^4 ~ (2x26)^4 ~ 52^4 = 7 311 616 .. pokud jsem to dobre pochopil, jedna se o variaci 4. tridy s opakovanim .. a nebo mi neco uniklo?
Pavel Tišnovský aura:98
26. 10. 2007 9:51 Nový

Re: OT: Způsob pojmenování chunků

celé vlákno
mate pravdu, jde o pouhe prepsani. velkych+malych znaku anglicke latinky je dohromady 52 a jsou vzdycky 4, tj. 52^4.
Zasílat nově přidané příspěvky e-mailem