-2

we have num 0x1234

In bigEndian:
low address -----------------> high address
0x12  |  0x34
In littleEndian:
low address -----------------> high address
0x34  |  0x12

we can see function below in binary.go:

func (bigEndian) PutUint16(b []byte, v uint16) {
    _ = b[1] // early bounds check to guarantee safety of writes below
    b[0] = byte(v >> 8)
    b[1] = byte(v)
}

I download golang code of x86 and powpc arch and find the same definition.

https://golang.org/dl/
go1.12.7.linux-ppc64le.tar.gz   Archive Linux   ppc64le 99MB    8eda20600d90247efbfa70d116d80056e11192d62592240975b2a8c53caa5bf3

Now let's see what happen in this function.

If cpu is little endian, we store 0x1234 in memory like this:

low address -----------------> high address

0x34  |  0x12

v >> 8 means shift 8 bits right, means /2^8, so we get this in memory:

low address -----------------> high address

0x12  |  0x00



byte(v>>8), we get byte 0x12 which is in low address -> b[0]

byte(v), we get byte 0x34 -> b[1]

so we get the result which i think it's right: [0x12,0x34]

===================================== If cpu is big endian, we store 0x1234 in memory like this:

low address -----------------> high address

0x12  |  0x34

v >> 8 means shift 8 bits right, means /2^8, so we get this in memory:

low address -----------------> high address

0x00  |  0x12

byte(v>>8), we get byte 0x00 which is in low address -> b[0]

byte(v), we get byte 0x12 -> b[1]

so we get the result which i think it's not right: [0x00,0x12]

I find in web how to check your cpu bigendian or little endian, and i write function below:

func IsBigEndian() bool {
    test16 := uint16(0x1234)
    test8 := *(*uint8)(unsafe.Pointer(&test16))
    if test8 == 0x12{
        return true
    }else{
        fmt.Printf("little")
        return false
    }
}

According to this function, I think byte() means get low address byte, am I right?

If right, why i get wrong result in analysis of "if cpu is big endian ..." ?

jumper
  • 5
  • 3
  • 3
    peterSO probably meant to link to https://commandcenter.blogspot.com/2012/04/byte-order-fallacy.html. – Peter Aug 08 '19 at 10:32
  • @Peter, thanks a lot. What really matters is the byte order of the data stream, which means that both the program that reads the file and the program that writes the file should agree on the byte order of the file (the data stream). For example, if a program on pc1(what ever big endian or little endian) wrote a file in big endian order, and a program on pc2(what ever big endian or little endian) read the same file in little endian order, it will fail. Am I right? – jumper Aug 09 '19 at 07:35
  • Yes, you have to pick the endianess for the file if you store binary data (for text formats it's already decided by the encoding). However, the code that deals with the file in no way depends on the endianess of the machine running that code. Not in Go nor any other language. In Go you just use either of binary.LittleEndian or binary.BigEndian consistently and you're done. – Peter Aug 09 '19 at 08:07
  • "If a program wrote a file in big endian order read the same file in little endian order, it will fail. Am I right?" Yes, kinda. It won't fail, technically, but yield wrong results (note that the [ByteOrder methods don't return errors](https://golang.org/pkg/encoding/binary/#ByteOrder)). – Peter Aug 09 '19 at 08:11

1 Answers1

0

thanks a lot @Volker, I found this post Does bit-shift depend on endianness? . And know "byte(xxx)" operate in processor's register which not depend on the endianness in memory, so byte(0x1234) always get 0x34.

jumper
  • 5
  • 3