Convert Little Endian to Big Endian

前端 未结 13 1825
慢半拍i
慢半拍i 2020-11-27 16:34

I just want to ask if my method is correct to convert from little endian to big endian, just to make sure if I understand the difference.

I have a number which is st

相关标签:
13条回答
  • 2020-11-27 16:48

    One slightly different way of tackling this that can sometimes be useful is to have a union of the sixteen or thirty-two bit value and an array of chars. I've just been doing this when getting serial messages that come in with big endian order, yet am working on a little endian micro.

    union MessageLengthUnion
    {
    
        uint16_t asInt;
        uint8_t asChars[2];
    
    };
    

    Then when I get the messages in I put the first received uint8 in .asChars[1], the second in .asChars[0] then I access it as the .asInt part of the union in the rest of my program.

    If you have a thirty-two bit value to store you can have the array four long.

    0 讨论(0)
  • 2020-11-27 16:48

    A Simple C program to convert from little to big

    #include <stdio.h>
    
    int main() {
    unsigned int little=0x1234ABCD,big=0;
    unsigned char tmp=0,l;
    
    printf(" Little endian little=%x\n",little);
    
    for(l=0;l < 4;l++) 
    {
        tmp=0;
        tmp = little | tmp;
        big = tmp | (big << 8);
        little = little >> 8;
    }
    printf(" Big endian big=%x\n",big);
    
    return 0;
    }
    
    0 讨论(0)
  • 2020-11-27 16:50

    one more suggestion :

    unsigned int a = 0xABCDEF23;
    a = ((a&(0x0000FFFF)) << 16) | ((a&(0xFFFF0000)) >> 16);
    a = ((a&(0x00FF00FF)) << 8) | ((a&(0xFF00FF00)) >>8);
    printf("%0x\n",a);
    
    0 讨论(0)
  • 2020-11-27 16:53

    Sorry, my answer is a bit too late, but it seems nobody mentioned built-in functions to reverse byte order, which in very important in terms of performance.

    Most of the modern processors are little-endian, while all network protocols are big-endian. That is history and more on that you can find on Wikipedia. But that means our processors convert between little- and big-endian millions of times while we browse the Internet.

    That is why most architectures have a dedicated processor instructions to facilitate this task. For x86 architectures there is BSWAP instruction, and for ARMs there is REV. This is the most efficient way to reverse byte order.

    To avoid assembly in our C code, we can use built-ins instead. For GCC there is __builtin_bswap32() function and for Visual C++ there is _byteswap_ulong(). Those function will generate just one processor instruction on most architectures.

    Here is an example:

    #include <stdio.h>
    #include <inttypes.h>
    
    int main()
    {
        uint32_t le = 0x12345678;
        uint32_t be = __builtin_bswap32(le);
    
        printf("Little-endian: 0x%" PRIx32 "\n", le);
        printf("Big-endian:    0x%" PRIx32 "\n", be);
    
        return 0;
    }
    

    Here is the output it produces:

    Little-endian: 0x12345678
    Big-endian:    0x78563412
    

    And here is the disassembly (without optimization, i.e. -O0):

            uint32_t be = __builtin_bswap32(le);
       0x0000000000400535 <+15>:    mov    -0x8(%rbp),%eax
       0x0000000000400538 <+18>:    bswap  %eax
       0x000000000040053a <+20>:    mov    %eax,-0x4(%rbp)
    

    There is just one BSWAP instruction indeed.

    So, if we do care about the performance, we should use those built-in functions instead of any other method of byte reversing. Just my 2 cents.

    0 讨论(0)
  • 2020-11-27 16:53

    "I swap each bytes right?" -> yes, to convert between little and big endian, you just give the bytes the opposite order. But at first realize few things:

    • size of uint32_t is 32bits, which is 4 bytes, which is 8 HEX digits
    • mask 0xf retrieves the 4 least significant bits, to retrieve 8 bits, you need 0xff

    so in case you want to swap the order of 4 bytes with that kind of masks, you could:

    uint32_t res = 0;
    b0 = (num & 0xff) << 24;        ; least significant to most significant
    b1 = (num & 0xff00) << 8;       ; 2nd least sig. to 2nd most sig.
    b2 = (num & 0xff0000) >> 8;     ; 2nd most sig. to 2nd least sig.
    b3 = (num & 0xff000000) >> 24;  ; most sig. to least sig.
    res = b0 | b1 | b2 | b3 ;
    
    0 讨论(0)
  • 2020-11-27 16:53

    I am assuming you are on linux

    Include "byteswap.h" & Use int32_t bswap_32(int32_t argument);

    It is logical view, In actual see, /usr/include/byteswap.h

    0 讨论(0)
提交回复
热议问题