แปลง endian ตัวใหญ่เป็น endian ตัวเล็กใน C [โดยไม่ต้องใช้ func ที่ให้มา] [ปิด]


93

ฉันต้องเขียนฟังก์ชันเพื่อแปลง endian ตัวใหญ่เป็น endian ตัวเล็กใน C. ฉันไม่สามารถใช้ฟังก์ชันไลบรารีใด ๆ


5
ค่า 16 บิต? 32 บิตค่า? ลอย? อาร์เรย์?
John Knoeller

20
อาจถึงเวลาเลือกคำตอบ?
Aniket Inge

7
การลงคะแนนเพื่อเปิดอีกครั้ง เหมือนกับstackoverflow.com/questions/105252/…สำหรับ C ++ เราสามารถแก้ไขเพื่อให้ชัดเจนขึ้น
Ciro Santilli 郝海东冠状病六四事件法轮功

คำตอบ:


173

สมมติว่าสิ่งที่คุณต้องการคือการแลกเปลี่ยนไบต์ง่ายๆลองสิ่งที่ชอบ

การแปลง 16 บิตที่ไม่ได้ลงนาม:

swapped = (num>>8) | (num<<8);

การแปลง 32 บิตที่ไม่ได้ลงชื่อ:

swapped = ((num>>24)&0xff) | // move byte 3 to byte 0
                    ((num<<8)&0xff0000) | // move byte 1 to byte 2
                    ((num>>8)&0xff00) | // move byte 2 to byte 1
                    ((num<<24)&0xff000000); // byte 0 to byte 3

สิ่งนี้จะสลับคำสั่งไบต์จากตำแหน่ง 1234 เป็น 4321 หากอินพุตของคุณคือ0xdeadbeefendian swap 32 บิตอาจมีเอาต์พุตเป็น0xefbeadde.

โค้ดด้านบนควรล้างด้วยมาโครหรืออย่างน้อยค่าคงที่แทนที่จะเป็นตัวเลขวิเศษ แต่หวังว่ามันจะช่วยได้เหมือนเดิม

แก้ไข: ในฐานะที่เป็นคำตอบอื่นที่ชี้ให้เห็นมีแพลตฟอร์ม OS และชุดคำสั่งทางเลือกเฉพาะซึ่งสามารถเร็วกว่าข้างต้นได้มาก ในเคอร์เนลลินุกซ์มีมาโคร (เช่น cpu_to_be32) ซึ่งจัดการกับ endianness ได้ค่อนข้างดี แต่ทางเลือกเหล่านี้เฉพาะสำหรับสภาพแวดล้อมของพวกเขา ในทางปฏิบัติ endianness จะจัดการได้ดีที่สุดโดยใช้แนวทางที่มีอยู่ผสมผสานกัน


5
+1 สำหรับการกล่าวถึงแพลตฟอร์ม / วิธีการเฉพาะฮาร์ดแวร์ โปรแกรมจะทำงานบนฮาร์ดแวร์บางตัวเสมอและคุณลักษณะของฮาร์ดแวร์จะเร็วที่สุดเสมอ
eonil

21
หากการแปลง 16 บิตเสร็จสิ้น((num & 0xff) >> 8) | (num << 8)gcc 4.8.3 จะสร้างrolคำสั่งเดียว และถ้าการแปลง 32 บิตถูกเขียนเป็น((num & 0xff000000) >> 24) | ((num & 0x00ff0000) >> 8) | ((num & 0x0000ff00) << 8) | (num << 24)คอมไพเลอร์เดียวกันจะสร้างbswapคำสั่งเดียว
user666412

ฉันไม่รู้ว่ามันมีประสิทธิภาพแค่ไหน แต่ฉันได้สลับลำดับไบต์กับบิตฟิลด์เช่นนี้ struct byte_t reverse(struct byte_t b) { struct byte_t rev; rev.ba = b.bh; rev.bb = b.bg; rev.bc = b.bf; rev.bd = b.be; rev.be = b.bd; rev.bf = b.bc; rev.bg = b.bb; rev.bh = b.ba; return rev;}โดยที่นี่คือบิตฟิลด์ที่มี 8 ฟิลด์ 1 บิต แต่ฉันไม่แน่ใจว่าเร็วเท่าคำแนะนำอื่น ๆ หรือไม่ สำหรับ ints ใช้union { int i; byte_t[sizeof(int)]; }เพื่อย้อนกลับไบต์โดยไบต์ในจำนวนเต็ม
Ilian Zapryanov

ฉันคิดว่านิพจน์ต้องเป็น: (num >> 8) | (num << 8) เพื่อย้อนกลับลำดับไบต์และ NOT: ((num & 0xff) >> 8) | (num << 8) ตัวอย่างที่ไม่ถูกต้องจะได้ศูนย์ในไบต์ต่ำ
jscom

@IlianZapryanov อาจจะ +1 เพื่อความชัดเจน แต่การใช้ bitfields ใน C เช่นนั้นน่าจะเป็นวิธีที่มีประสิทธิภาพน้อยที่สุด
sherrellbc

105

โดยรวม:

#include <byteswap.h>

คุณสามารถรับฟังก์ชั่นการแลกเปลี่ยนไบต์ที่ขึ้นอยู่กับเครื่องได้ จากนั้นคุณสามารถใช้ฟังก์ชันต่อไปนี้ได้อย่างง่ายดาย:

__bswap_32 (uint32_t input)

หรือ

__bswap_16 (uint16_t input)

3
ขอบคุณสำหรับคำตอบ แต่ฉันไม่สามารถใช้ฟังก์ชันห้องสมุดใด ๆ ได้
Mark Ransom

4
ควรอ่าน#include <byteswap.h>ดู comment ในไฟล์. h เอง โพสต์นี้มีข้อมูลที่เป็นประโยชน์ดังนั้นฉันจึงโหวตขึ้นแม้ว่าผู้เขียนจะเพิกเฉยต่อข้อกำหนด OP ที่จะไม่ใช้ฟังก์ชัน lib
Eli Rosencruft

30
ในความเป็นจริงฟังก์ชัน __bswap_32 / __ bswap_16 เป็นมาโครและไม่ใช่ฟังก์ชันไลบรารีซึ่งเป็นอีกเหตุผลหนึ่งในการโหวต
Eli Rosencruft

7
ความเข้าใจของฉันคือไม่รับประกันว่าส่วนหัวนี้จะมีอยู่สำหรับระบบปฏิบัติการทั้งหมดในทุกสถาปัตยกรรม ฉันยังไม่พบวิธีแบบพกพาในการจัดการกับปัญหา endian
Edward Falk

2
ไม่มีอยู่บน windows - อย่างน้อยก็ไม่มีเมื่อคอมไพล์ข้ามจาก linux ด้วย mingw 32 หรือ 64 บิต
bph

61
#include <stdint.h>


//! Byte swap unsigned short
uint16_t swap_uint16( uint16_t val ) 
{
    return (val << 8) | (val >> 8 );
}

//! Byte swap short
int16_t swap_int16( int16_t val ) 
{
    return (val << 8) | ((val >> 8) & 0xFF);
}

//! Byte swap unsigned int
uint32_t swap_uint32( uint32_t val )
{
    val = ((val << 8) & 0xFF00FF00 ) | ((val >> 8) & 0xFF00FF ); 
    return (val << 16) | (val >> 16);
}

//! Byte swap int
int32_t swap_int32( int32_t val )
{
    val = ((val << 8) & 0xFF00FF00) | ((val >> 8) & 0xFF00FF ); 
    return (val << 16) | ((val >> 16) & 0xFFFF);
}

อัปเดต : เพิ่มการแลกเปลี่ยนไบต์ 64 บิต

int64_t swap_int64( int64_t val )
{
    val = ((val << 8) & 0xFF00FF00FF00FF00ULL ) | ((val >> 8) & 0x00FF00FF00FF00FFULL );
    val = ((val << 16) & 0xFFFF0000FFFF0000ULL ) | ((val >> 16) & 0x0000FFFF0000FFFFULL );
    return (val << 32) | ((val >> 32) & 0xFFFFFFFFULL);
}

uint64_t swap_uint64( uint64_t val )
{
    val = ((val << 8) & 0xFF00FF00FF00FF00ULL ) | ((val >> 8) & 0x00FF00FF00FF00FFULL );
    val = ((val << 16) & 0xFFFF0000FFFF0000ULL ) | ((val >> 16) & 0x0000FFFF0000FFFFULL );
    return (val << 32) | (val >> 32);
}

สำหรับตัวแปรint32_tและint64_tตัวแปรอะไรคือเหตุผลที่อยู่เบื้องหลังการปิดบัง... & 0xFFFFและ... & 0xFFFFFFFFULL? มีบางอย่างเกิดขึ้นกับส่วนขยายเครื่องหมายที่นี่ฉันไม่เห็นหรือไม่ แล้วทำไมถึงswap_int64กลับมาuint64_t? ไม่ควรอย่างนั้นint64_tหรือ?
bgoodr

1
swap_int64 ส่งคืน uint64 เป็นข้อผิดพลาด การกำบังด้วยค่า int ที่มีการลงนามนั้นเป็นการลบเครื่องหมายออก การเลื่อนไปทางขวาจะฉีดบิตเครื่องหมายทางด้านซ้าย เราสามารถหลีกเลี่ยงสิ่งนี้ได้โดยเพียงแค่เรียกการดำเนินการสลับ int ที่ไม่ได้ลงชื่อ
chmike

ขอบคุณ. คุณอาจต้องการเปลี่ยนประเภทของค่าส่งคืนswap_int64ในคำตอบของคุณ +1 สำหรับคำตอบที่เป็นประโยชน์ BTW!
bgoodr

endian บิตและค่าขึ้นอยู่กับ?
MarcusJ

1
สิ่งLLที่ไม่จำเป็น(u)swap_uint64()มากเช่นLไม่จำเป็นใน(u)swap_uint32(). Uไม่จำเป็นต้องใช้ในuswap_uint64()มากเช่นUไม่จำเป็นต้องใช้ในuswap_uint32()
Chux - คืนสิทธิ์ให้กับโมนิกา

13

นี่เป็นเวอร์ชันที่ค่อนข้างทั่วไป ฉันยังไม่ได้รวบรวมมันจึงอาจมีการพิมพ์ผิด แต่คุณควรเข้าใจ

void SwapBytes(void *pv, size_t n)
{
    assert(n > 0);

    char *p = pv;
    size_t lo, hi;
    for(lo=0, hi=n-1; hi>lo; lo++, hi--)
    {
        char tmp=p[lo];
        p[lo] = p[hi];
        p[hi] = tmp;
    }
}
#define SWAP(x) SwapBytes(&x, sizeof(x));

หมายเหตุ:สิ่งนี้ไม่ได้ปรับให้เหมาะกับความเร็วหรือพื้นที่ มีวัตถุประสงค์เพื่อให้ชัดเจน (ง่ายต่อการแก้ไขข้อบกพร่อง) และพกพาได้

อัปเดต 2018-04-04 เพิ่มการยืนยัน () เพื่อดักจับกรณีที่ไม่ถูกต้องของ n == 0 ตามที่ผู้แสดงความคิดเห็น @chux เห็น


1
คุณสามารถใช้ xorSwap เพื่อประสิทธิภาพที่ดีขึ้น ชอบเวอร์ชันทั่วไปนี้มากกว่าทุกขนาดที่ระบุ ...

ฉันทดสอบแล้วปรากฎว่าเร็วกว่า xorSwap ... บน x86 stackoverflow.com/questions/3128095/…

1
@nus - ข้อดีอย่างหนึ่งของโค้ดที่ง่ายมากคือบางครั้งตัวเพิ่มประสิทธิภาพคอมไพเลอร์สามารถทำให้มันเร็วมาก
Michael J

@MichaelJ OTOH เวอร์ชัน 32 บิตด้านบนในคำตอบของ chmike ได้รับการรวบรวมเป็นbswapคำสั่งเดียวโดยคอมไพเลอร์ X86 ที่เหมาะสมพร้อมเปิดใช้งานการเพิ่มประสิทธิภาพ เวอร์ชันที่มีพารามิเตอร์สำหรับขนาดนี้ไม่สามารถทำได้
Alnitak

@Alnitak - อย่างที่ฉันพูดไปฉันไม่ได้พยายามเพิ่มประสิทธิภาพรหัสของฉันเลย เมื่อผู้ใช้ nus พบว่าโค้ดทำงานเร็วมาก (ในกรณีหนึ่ง) ฉันเพิ่งพูดถึงแนวคิดทั่วไปที่คอมไพเลอร์สามารถปรับโค้ดอย่างง่ายได้ รหัสของฉันใช้งานได้หลากหลายกรณีและค่อนข้างเข้าใจง่ายและง่ายต่อการดีบัก ตรงตามวัตถุประสงค์ของฉัน
Michael J

9

หากคุณต้องการมาโคร (เช่นระบบฝังตัว):

#define SWAP_UINT16(x) (((x) >> 8) | ((x) << 8))
#define SWAP_UINT32(x) (((x) >> 24) | (((x) & 0x00FF0000) >> 8) | (((x) & 0x0000FF00) << 8) | ((x) << 24))

มาโครเหล่านี้ใช้ได้ แต่ ((x) >> 24) จะล้มเหลวเมื่อจำนวนเต็มที่ลงนามอยู่ระหว่าง 0x80000000 ถึง 0xffffffff เป็นความคิดที่ดีที่จะใช้บิตและที่นี่ หมายเหตุ: ((x) << 24) ปลอดภัยอย่างสมบูรณ์ (x) >> 8) จะล้มเหลวเช่นกันหาก 16 บิตสูงไม่ใช่ศูนย์ (หรือมีการระบุค่า 16 บิตที่มีการลงชื่อ)

2
@ PacMan - มาโครเหล่านี้มีไว้เพื่อใช้สลับจำนวนเต็มที่ไม่ได้ลงชื่อเท่านั้น นั่นเป็นเหตุผลว่าทำไมจึงมีUINTชื่อของพวกเขา
ต.ค.

ใช่จริงขออภัยสำหรับเสียง การฝังตัวพิมพ์ดีดจะดีที่สุดไม่ใช่หรือ?

5

แก้ไข:นี่คือฟังก์ชันไลบรารี ทำตามขั้นตอนเหล่านี้ด้วยตนเอง

ผมตะลึงอย่างแน่นอนโดยจำนวนของคนที่ไม่รู้__byteswap_ushort, __byteswap_ulong และ __byteswap_uint64 แน่นอนว่าเป็น Visual C ++ ที่เฉพาะเจาะจง แต่พวกเขารวบรวมโค้ดแสนอร่อยบนสถาปัตยกรรม x86 / IA-64 :)

นี่คือการใช้bswapคำสั่งอย่างชัดเจนซึ่งดึงมาจากหน้านี้ หมายเหตุว่ารูปแบบที่แท้จริงข้างต้นจะเสมอจะเร็วกว่านี้ฉันเพิ่มเพียง แต่มันจะให้คำตอบโดยไม่ต้องประจำห้องสมุด

uint32 cq_ntohl(uint32 a) {
    __asm{
        mov eax, a;
        bswap eax; 
    }
}

21
สำหรับคำถาม C คุณกำลังแนะนำสิ่งที่เฉพาะเจาะจงสำหรับ Visual C ++ หรือไม่?
Alok Singhal

3
@Alok: Visual C ++ เป็นผลิตภัณฑ์ของ Microsoft ใช้งานได้ดีสำหรับการรวบรวมรหัส C :)
Sam Harwell

20
ทำไมคุณถึงทำให้คุณตกใจที่หลายคนไม่ทราบถึงการใช้งาน Byteswapping เฉพาะของ Microsoft
dreamlax

36
เป็นข้อมูลที่ดีสำหรับทุกคนที่พัฒนาผลิตภัณฑ์แบบปิดซึ่งไม่จำเป็นต้องพกพาหรือเป็นไปตามมาตรฐาน
Sam โพสต์

6
@Alok, OP ไม่ได้กล่าวถึงคอมไพเลอร์ | OS. บุคคลได้รับอนุญาตให้ตอบตามประสบการณ์ของเขาด้วยชุดเครื่องมือเฉพาะ
Aniket Inge

5

เป็นเรื่องตลก:


#include <stdio.h>

int main (int argc, char *argv[])
{
    size_t sizeofInt = sizeof (int);
    int i;

    union
    {
        int x;
        char c[sizeof (int)];
    } original, swapped;

    original.x = 0x12345678;

    for (i = 0; i < sizeofInt; i++)
        swapped.c[sizeofInt - i - 1] = original.c[i];

    fprintf (stderr, "%x\n", swapped.x);

    return 0;
}

7
ฮ่าฮ่าฮ่าฮ่าฮ่า. ฮ่า ๆ ๆ . ฮ่า. ฮา? (เรื่องตลกอะไร)

3
คุณดึงสิ่งนี้มาจากที่เก็บซอร์สของ Windows หรือไม่? :)
hochl

Nodejs ใช้เทคนิคนี้! github.com/nodejs/node/blob/…
Justin Moser

น่าใช้int i, size_t sizeofIntและไม่ใช่ประเภทเดียวกันสำหรับทั้งสองอย่าง
chux - คืนสถานะ Monica

5

นี่คือวิธีการใช้คำสั่ง SSSE3 pshufb โดยใช้ Intel intrinsic โดยสมมติว่าคุณมีผลคูณของ 4 ints:

unsigned int *bswap(unsigned int *destination, unsigned int *source, int length) {
    int i;
    __m128i mask = _mm_set_epi8(12, 13, 14, 15, 8, 9, 10, 11, 4, 5, 6, 7, 0, 1, 2, 3);
    for (i = 0; i < length; i += 4) {
        _mm_storeu_si128((__m128i *)&destination[i],
        _mm_shuffle_epi8(_mm_loadu_si128((__m128i *)&source[i]), mask));
    }
    return destination;
}

3

จะทำงาน / เร็วกว่านี้ไหม

 uint32_t swapped, result;

((byte*)&swapped)[0] = ((byte*)&result)[3];
((byte*)&swapped)[1] = ((byte*)&result)[2];
((byte*)&swapped)[2] = ((byte*)&result)[1];
((byte*)&swapped)[3] = ((byte*)&result)[0];

2
ฉันคิดว่าคุณหมายถึงไม่ได้char byte
dreamlax

เมื่อใช้กลยุทธ์นี้โซลูชันที่มีคะแนนโหวตมากที่สุดเมื่อเทียบกับของคุณจะเทียบเท่าและมีประสิทธิภาพและพกพาได้มากที่สุด อย่างไรก็ตามวิธีแก้ปัญหาที่ฉันเสนอ (คะแนนโหวตมากเป็นอันดับสอง) ต้องการการดำเนินการน้อยลงและควรมีประสิทธิภาพมากขึ้น
chmike

1

นี่คือฟังก์ชั่นที่ฉันใช้ - ทดสอบและใช้งานได้กับข้อมูลพื้นฐานทุกประเภท:

//  SwapBytes.h
//
//  Function to perform in-place endian conversion of basic types
//
//  Usage:
//
//    double d;
//    SwapBytes(&d, sizeof(d));
//

inline void SwapBytes(void *source, int size)
{
    typedef unsigned char TwoBytes[2];
    typedef unsigned char FourBytes[4];
    typedef unsigned char EightBytes[8];

    unsigned char temp;

    if(size == 2)
    {
        TwoBytes *src = (TwoBytes *)source;
        temp = (*src)[0];
        (*src)[0] = (*src)[1];
        (*src)[1] = temp;

        return;
    }

    if(size == 4)
    {
        FourBytes *src = (FourBytes *)source;
        temp = (*src)[0];
        (*src)[0] = (*src)[3];
        (*src)[3] = temp;

        temp = (*src)[1];
        (*src)[1] = (*src)[2];
        (*src)[2] = temp;

        return;
    }

    if(size == 8)
    {
        EightBytes *src = (EightBytes *)source;
        temp = (*src)[0];
        (*src)[0] = (*src)[7];
        (*src)[7] = temp;

        temp = (*src)[1];
        (*src)[1] = (*src)[6];
        (*src)[6] = temp;

        temp = (*src)[2];
        (*src)[2] = (*src)[5];
        (*src)[5] = temp;

        temp = (*src)[3];
        (*src)[3] = (*src)[4];
        (*src)[4] = temp;

        return;
    }

}

2
รหัสขึ้นอยู่กับสมมติฐานที่สมเหตุสมผล: sourceมีการจัดตำแหน่งตามความจำเป็น - แต่ถ้าไม่ถือสมมติฐานนั้นรหัสจะเป็น UB
chux - คืนสถานะ Monica

1

แก้ไข: ฟังก์ชั่นนี้จะแลกเปลี่ยนเฉพาะความสมบูรณ์ของคำ 16 บิตที่จัดชิดกันเท่านั้น ฟังก์ชันมักจำเป็นสำหรับการเข้ารหัส UTF-16 / UCS-2 แก้ไข END

หากคุณต้องการเปลี่ยนจุดสิ้นสุดของบล็อกความทรงจำคุณสามารถใช้วิธีการที่รวดเร็วอย่างเห็นได้ชัด อาร์เรย์หน่วยความจำของคุณควรมีขนาดเท่ากับ 8

#include <stddef.h>
#include <limits.h>
#include <stdint.h>

void ChangeMemEndianness(uint64_t *mem, size_t size) 
{
uint64_t m1 = 0xFF00FF00FF00FF00ULL, m2 = m1 >> CHAR_BIT;

size = (size + (sizeof (uint64_t) - 1)) / sizeof (uint64_t);
for(; size; size--, mem++)
  *mem = ((*mem & m1) >> CHAR_BIT) | ((*mem & m2) << CHAR_BIT);
}

ฟังก์ชันประเภทนี้มีประโยชน์สำหรับการเปลี่ยนจุดสิ้นสุดของไฟล์ Unicode UCS-2 / UTF-16


ไม่มี CHAR_BIT #define เพื่อทำให้โค้ดสมบูรณ์
Tõnu Samuel

โอเคฉันเพิ่มรายการรวมที่ขาดหายไปแล้ว
Patrick Schlüter

นี่คือลิงค์ไปยัง swap ใน C ++ ฉันไม่t know if itเร็วเท่าที่คำแนะนำ แต่มันจะเปลี่ยนไป: github.com/heatblazer/helpers/blob/master/utils.h
Ilian Zapryanov

CHAR_BITแทนที่จะ8เป็นอยากรู้ว่าจะขึ้นอยู่กับ0xFF00FF00FF00FF00ULL CHAR_BIT == 8โปรดทราบว่าLLไม่จำเป็นต้องใช้ค่าคงที่
chux - คืนสถานะ Monica

คุณพูดถูก เขียนด้วยCHAR_BITเพื่อเพิ่มการเปิดรับแสงของมาโครนั้นเท่านั้น สำหรับ LL มันเป็นคำอธิบายประกอบมากกว่าสิ่งอื่นใด นอกจากนี้ยังเป็นนิสัยที่ฉันจับได้เมื่อนานมาแล้วด้วยคอมไพเลอร์ buggy (มาตรฐานก่อน) ซึ่งจะไม่ทำสิ่งที่ถูกต้อง
Patrick Schlüter

1

ข้อมูลโค้ดนี้สามารถแปลงหมายเลข Endian ขนาดเล็ก 32 บิตเป็นหมายเลข Big Endian

#include <stdio.h>
main(){    
    unsigned int i = 0xfafbfcfd;
    unsigned int j;    
    j= ((i&0xff000000)>>24)| ((i&0xff0000)>>8) | ((i&0xff00)<<8) | ((i&0xff)<<24);    
    printf("unsigned int j = %x\n ", j);    
}

ขอบคุณ @YuHao ฉันเป็นคนใหม่ที่นี่ไม่รู้จะจัดรูปแบบข้อความอย่างไร
Kaushal Billore

2
การใช้งาน((i>>24)&0xff) | ((i>>8)&0xff00) | ((i&0xff00)<<8) | (i<<24);อาจเร็วกว่าในบางแพลตฟอร์ม (เช่นการรีไซเคิลค่าคงที่ AND มาสก์) แม้ว่าคอมไพเลอร์ส่วนใหญ่จะทำเช่นนี้ แต่คอมไพเลอร์ธรรมดาบางตัวไม่สามารถปรับให้เหมาะกับคุณได้

-7

หากคุณรันบนโปรเซสเซอร์ x86 หรือ x86_64 big endian จะเป็นแบบเนทีฟ ดังนั้น

สำหรับค่า 16 บิต

unsigned short wBigE = value;
unsigned short wLittleE = ((wBigE & 0xFF) << 8) | (wBigE >> 8);

สำหรับค่า 32 บิต

unsigned int   iBigE = value;
unsigned int   iLittleE = ((iBigE & 0xFF) << 24)
                        | ((iBigE & 0xFF00) << 8)
                        | ((iBigE >> 8) & 0xFF00)
                        | (iBigE >> 24);

นี่ไม่ใช่วิธีแก้ปัญหาที่มีประสิทธิภาพสูงสุดเว้นแต่คอมไพเลอร์จะรับรู้ว่านี่เป็นการจัดการระดับไบต์และสร้างรหัสแลกเปลี่ยนไบต์ แต่มันไม่ได้ขึ้นอยู่กับเทคนิคการจัดวางหน่วยความจำใด ๆ และสามารถเปลี่ยนเป็นมาโครได้อย่างง่ายดาย


25
บนสถาปัตยกรรม x86 และ x86_64 โครงร่าง endian เล็ก ๆ เป็นแบบดั้งเดิม
MK aka Grisu
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.