大端模式,是指數據的高位元組保存在記憶體的低地址中,而數據的低位元組保存在記憶體的高地址中,這樣的存儲模式有點兒類似於把數據當作字元串順序處理:地址由小向大增加,而數據從高位往低位放;這和我們的閱讀習慣一致。
小端模式,是指數據的高位元組保存在記憶體的高地址中,而數據的低位元組保存在記憶體的低地址中,這種存儲模式將地址的高低和數據位權有效地結合起來,高地址部分權值高,低地址部分權值低。
基本介紹
- 中文名:大小端模式
- 外文名:Big-endian/Little-endian
簡明區分
---------------
buf[3] (0x78) -- 低位
buf[2] (0x56)
buf[1] (0x34)
buf[0] (0x12) -- 高位
---------------
低地址
---------------
buf[3] (0x12) -- 高位
buf[2] (0x34)
buf[1] (0x56)
buf[0] (0x78) -- 低位
--------------
記憶體地址 | 小端模式存放內容 | 大端模式存放內容 |
0x4000 | 0x78 | 0x12 |
0x4001 | 0x56 | 0x34 |
0x4002 | 0x34 | 0x56 |
0x4003 | 0x12 | 0x78 |
名詞解析
short int x;char x0,x1;x=0x1122;x0=((char*)&x)[0]; //低地址單元x1=((char*)&x)[1]; //高地址單元
#definesw16(x)\ ((short)(\ (((short)(x)&(short)0x00ffU)<<8)|\ (((short)(x)&(short)0xff00U)>>8)))
作業系統
static union { char c[4]; unsigned long l; }endian_test = { { 'l', '?', '?', 'b' } };#define ENDIANNESS ((char)endian_test.l)
判斷處理器
' 注意這個CopyMemory的聲明與一般的不一樣,' 一般的都是(pDst As Any, pSrc As Any, ByVal ByteLen As Long)' 為了能夠逐位元組訪問u,所以前面兩個參數改成了按值傳遞,配合VarPtr函式獲取變數地址Private Declare Sub CopyMemory Lib "kernel32" Alias _ "RtlMoveMemory" (ByVal pDst As Long, ByVal pSrc As Long, ByVal ByteLen As Long)Private Sub Form_Load() ' VB的Integer占用2個位元組!Long才是4個位元組 ' 32位應用程式的指針是4個位元組 Dim uptr As Long Dim aptr As Long Dim bptr As Long Dim cptr As Long Dim dptr As Long Dim u As Long ' 儲存u從低地址到高地址的4個位元組 Dim a As Byte Dim b As Byte Dim c As Byte Dim d As Byte u = 367328153 ' 十六進制數:15 E4 FB 99 uptr = VarPtr(u) ' VarPtr函式是內置函式,但是msdn不說,作用是獲取變數的地址 aptr = VarPtr(a) bptr = VarPtr(b) cptr = VarPtr(c) dptr = VarPtr(d) CopyMemory aptr, uptr + 0, 1 ' 將u逐位元組按順序寫入a,b,c,d CopyMemory bptr, uptr + 1, 1 CopyMemory cptr, uptr + 2, 1 CopyMemory dptr, uptr + 3, 1 ' Windows系統,英特爾處理器:最後輸出的是99 FB E4 15 MsgBox Hex(a) & " " & Hex(b) & " " & Hex(c) & " " & Hex(d)End Sub
#include <iostream>using namespace std;typedef unsigned char byte;// 轉換char(視為整數類型)為16進制字元串void ChtoHex(byte Val, char* dest){ // 輾轉相除法,倒序看得到結果 byte tmp = Val % 16; if (tmp >= 0 && tmp <= 9) { dest[1] = '0' + tmp; } else if (tmp >= 10 && tmp <= 15) { dest[1] = 'A' + tmp - 10; } tmp = (Val/16) % 16; if (tmp >= 0 && tmp <= 9) { dest[0] = '0' + tmp; } else if (tmp >= 10 && tmp <= 15) { dest[0] = 'A' + tmp - 10; } // 設定'\0' dest[2] = '\0';}// 主函式int main(){ int u = 367328153; // 原始數據,8位16進制為15 E4 FB 99 byte a, b, c, d; // u從低地址到高地址的四個位元組 // a~d對應的16進制字元串,預留3個字元 char Sa[3], Sb[3], Sc[3], Sd[3]; byte* k = (byte*)&u; a = k[0]; b = k[1]; c = k[2]; d = k[3]; // 轉成16進制字元串 ChtoHex(a, Sa); ChtoHex(b, Sb); ChtoHex(c, Sc); ChtoHex(d, Sd); cout << Sa << " " << Sb << " " << Sc << " " << Sd << endl; system("pause"); return 0;}
#include <stdio.h>typedef unsigned char byte;// 轉換char(視為整數類型)為16進制字元串void ChtoHex(byte Val, char* dest){ // 輾轉相除法,倒序看得到結果 byte tmp = Val % 16; if (tmp >= 0 && tmp <= 9) { dest[1] = '0' + tmp; } else if (tmp >= 10 && tmp <= 15) { dest[1] = 'A' + tmp - 10; } tmp = (Val/16) % 16; if (tmp >= 0 && tmp <= 9) { dest[0] = '0' + tmp; } else if (tmp >= 10 && tmp <= 15) { dest[0] = 'A' + tmp - 10; } // 設定\0 dest[2] = '\0';}// 主函式void main(){ int u = 367328153; // 原始數據,8位16進制為15 E4 FB 99 byte a, b, c, d; // u從低地址到高地址的四個位元組 // a~d對應的16進制字元串,預留3個字元 char Sa[3], Sb[3], Sc[3], Sd[3]; byte* k = (byte*)&u; a = k[0]; b = k[1]; c = k[2]; d = k[3]; // 轉成16進制字元串 ChtoHex(a, Sa); ChtoHex(b, Sb); ChtoHex(c, Sc); ChtoHex(d, Sd); printf("%s %s %s %s\n", Sa, Sb, Sc, Sd); scanf_s("%d", &a);}
using System;namespace ConsoleApplication1{ class Program { static void Main(string[] args) { int u = 367328153; // 原始數據,8位16進制為15 E4 FB 99 byte[] bytes; // u從低地址到高地址的四個位元組 // 獲取 bytes = System.BitConverter.GetBytes(u); Console.WriteLine( bytes[0].ToString("X") + " " + bytes[1].ToString("X") + " " + bytes[2].ToString("X") + " " + bytes[3].ToString("X") ); Console.ReadLine(); } }}
#include "stm32f4xx.h"int main(void){ int u = 367328153; // 原始數據15 E4 FB 99 int* k = &u; return 0;}
#include <reg52.h>int main(){ int longbit = sizeof(long); long u = 367328153; // 原始數據15 E4 FB 99 long* k = &u; return 0;}