2021年12月15日 星期三

Little and Big Endianess, Network Byte Order, Host Byte Order

https://en.wikipedia.org/wiki/Endianness


Boiled Egg

In Gulliver's Travels, there is a discussion about how to break the shell of a boiled egg from the big of little end.


C programming

int x = 0x01234567;  // x has 4 bytes, low byte is 67
&x;  // address of &x is 0x100

Then x actually occupies 4 bytes at addresses of 0x100, 0x101, 0x102, 0x103.

if the high byte of 01 is stored at low address of 0x100, it is called big endianess.
If the low byte of 67 is stored at low address of 0x100, it is called little endianess.

x86 (i386) CPU uses little endianess. CPU order means host byte order.

Network byte order uses big endianess.


Berkeley Socket API

hotn means host byte order to network byte order
ntoh means network byte order to host byte order

#include <arpa/inet.h>
uint32_t htonl(uint32_t hostlong);
uint16_t htons(uint16_t hostshort);
uint32_t ntohl(uint32_t netlong);
uint16_t ntohs(uint16_t netshort);


C++ CPU endianess check

const int num = 1;
if (*(char *)&num == 1) {
    printf("Little-Endian\n");  # AMD Ryzen
} else {
    printf("Big-Endian\n");
}

Python CPU endianess check

import sys
print(sys.byteorder)  #  'little' on AMD Ryzen


Ubuntu endianess check

Terminal lscpu says AMD Ryzen uses Littel Endian

$ lscpu
Architecture:                    x86_64
CPU op-mode(s):                  32-bit, 64-bit
Byte Order:                      Little Endian
Address sizes:                   43 bits physical, 48 bits virtual
CPU(s):                          16
On-line CPU(s) list:             0-15
Thread(s) per core:              2
Core(s) per socket:              8
Socket(s):                       1
NUMA node(s):                    1
Vendor ID:                       AuthenticAMD
CPU family:                      23
Model:                           113
Model name:                      AMD Ryzen 7 3700X 8-Core Processor

Python to bytes(byteorder='big' or 'small')

16 0x10
32 0x20
64 0x40
128 0x80
256 0x100
512 0x200
1024 0x400 or 0x0400

(1024).to_bytes(2, byteorder='big')  # 0x0400
b'\x04\x00'
(1025).to_bytes(2, byteorder='big')  # 0x0401
b'\x04\x01'  # MSB at beginning of byte array

Python 0x01234567 to bytes

(0x01234567).to_bytes(4, byteorder='big')  # network byte order
b'\x01#Eg'  # 01 23 45 67  #MSB 01 at beginning of byte array (big endian is natural for human)

(0x01234567).to_bytes(4, byteorder='little')  # host byte order
b'gE#\x01  # 67 45 23 01 # MSB 01 at end of byte array,

C++ memcpy

int main() {
char buffer[4] = {};
unsigned int ival = 0x01234567;
memcpy(buffer, (char*)&ival, sizeof(unsigned int));
hexdump(buffer, 4);
return 0;
}

000000: 67 45 23 01                                      gE#.

// LSB 67 is at begin of byte array (low address), little endianess
// MSB 01 at end of byte array, i.e. little endian by memcpy()



沒有留言:

張貼留言

2023 Promox on Morefine N6000 16GB 512GB

2023 Promox on Morefine N6000 16GB 512GB Software Etcher 100MB (not but can be rufus-4.3.exe 1.4MB) Proxmox VE 7.4 ISO Installer (1st ISO re...