Reja:
1. Bayt tartibi
2. yuqori bayt
3. Qayta ishlash baytlari
Bayt tartibi
Biz odatda baytni eng kichik ma'lumotlar birligi deb hisoblaymiz. Albatta, aslida bayt 8 bitni
ham o'z ichiga oladi (bit = ikkilik raqam). 32 bitli protsessorda "so'z uzunligi" 32 bit, ya'ni 4
bayt. Bunday protsessorda xotira har doim 4 baytli hizalanishda o'qiladi yoki yoziladi, shuning
uchun xotirada o'sha 4 baytli ma'lumotlar qanday tartibda saqlanadi? Buni quyida batafsilroq
muhokama qilaylik.
Endianness quyidagilarni o'z ichiga oladi: katta endian va katta endian. Nima uchun
toifalarga ajratish shunchalik qiyin? Masalan, 255 ikkilik shaklda 1111 1111 sifatida ifodalanadi,
plyus 1 - 1 00000000 va qo'shimcha 1 qo'shiladi. Shubhasiz, biz bu 1ni saqlash uchun qo'shimcha
baytdan foydalanishimiz kerak, lekin bu 1ni birinchisida saqlash kerak. bayt yoki ikkinchi
bayt? Hozirgi kunda odamlar boshqacha tanlaganlari uchun katta endian va katta endian o'rtasida
farq bor.
Buyuk endian buyrug'i "yuqori bayt" past manzilga o'tadigan saqlash usulini
bildiradi. Masalan, ax manziliga 0x0A0B0C0D yozilgandan so'ng, xotiradagi ma'lumotlar
quyidagicha bo'ladi:
"Past bayt" ni past manzilga qo'yadigan katta endian usuli uchun buning aksi. Masalan:
Intel kabi tez -tez ishlatib turadigan protsessor arxitekturasi uchun AMD protsessorlari past
baytli tartibdan foydalanadi va masalan, ilgari Mac OS ishlatadigan Power PC katta baytli
tartibdan foydalanadi (lekin hozir Mac OS Intel CPU Up -dan ham foydalanadi).
Qayta ishlash baytlari
Go encoding/binary-da muhim bo'lmagan bayt tartibini boshqarish kodi BigEndian global
o'zgaruvchisida katta endian ma'lumotlarini boshqarish uchun ishlatiladi va LittleEndian katta
endian ma'lumotlarini boshqarish uchun ishlatiladi. Ushbu ikkita o'zgaruvchiga mos keladigan
ma'lumotlar turlari ByteOrder interfeysini amalga oshiradi:
ByteOrder interfeysi yozing {
Uint16 ([] bayt) uint16
Uint32 ([] bayt) uint32
Uint64 ([] bayt) uint64
PutUint16 ([] bayt, uint16)
PutUint32 ([] bayt, uint32)
PutUint64 ([] bayt, uint64)
String () qatori
}
Ular orasida dastlabki uchta usul ma'lumotlarni o'qish uchun, oxirgi uchta usul esa
ma'lumotlarni yozish uchun ishlatiladi.
Siz yuqorida ko'rsatilgan usullar imzo qo'yilmagan butun sonlar bilan ishlashini sezishingiz
mumkin. Agar biz imzolangan tamsayılar bilan ishlashni xohlasak nima bo'ladi? Bu juda oddiy,
faqat majburiy konvertatsiya:
FunIn Put32 (b [] bayt, v int32) {
binary.BigEndian.PutUint32 (b, uint32 (v))
}
Ular haqida chuqurroq ma'lumotga ega bo'lish uchun keling, buyuk endian va katta endian
tartibi qanday ketishini kuzatadigan dastur yozaylik:
asosiy paket
Import (
"kodlash / ikkilik"
"fmt"
"xavfli"
)
const INT_SIZE int = int (xavfsiz bo'lmagan o'lcham (0))
// Tizimimizdagi bayt turini aniqlang
Funks tizimiEdian () {
var i int = 0x1
bs: = (* [INT_SIZE] bayt) (xavfli.Pinter (& i))
agar bs [0] == 0 {
fmt.Println ("tizimli edian - endi endian")
} boshqa {
fmt.Println ("tizimli edian katta endian")
}
}
func testBigEndian () {
// 0000 0000 0000 0000 0000 0000 0001 1111 1111
var testInt int32 = 256
fmt.Printf ("% d katta endianni ishlatadi: \ n", testInt)
var testBytes [] bayt = qilish ([] bayt, 4)
binary.BigEndian.PutUint32 (testBytes, uint32 (testInt))
fmt.Println ("int32 dan baytlarga:", testBytes)
convInt: = binary.BigEndian.Uint32 (testBytes)
fmt.Printf ("bayt int32:% d \ n \ n", convInt)
}
func testLittleEndian () {
// 0000 0000 0000 0000 0000 0000 0001 1111 1111
var testInt int32 = 256
fmt.Printf ("% d kichik endianni ishlatadi: \ n", testInt)
var testBytes [] bayt = qilish ([] bayt, 4)
binary.LittleEndian.PutUint32 (testBytes, uint32 (testInt))
fmt.Println ("int32 dan baytlarga:", testBytes)
convInt: = binary.LittleEndian.Uint32 (testBytes)
fmt.Printf ("bayt int32:% d \ n \ n", convInt)
}
Do'stlaringiz bilan baham: |