1. 程式人生 > >字節與小端、大端法存儲。

字節與小端、大端法存儲。

spa sizeof 另一個 深入理解 eight 代碼 tar http 數據類型

以下僅為個人學習的記錄,如有疏漏不妥之處,還請不吝賜教

字節(byte)這個術語由 Werner Buchholz在1956年創造的。在此之前,字節通常稱為syllable.

歷史上,字節並非一定是8位的,但現在基本都是以8位作為1個字節。最開始字節是用來為字符編碼的。C語言中的用char類型為字符編碼,占1字節。可是1個字節最多只能存放256組合,也就是說,1個字節最多能表示256種字符。因此需要多個字節來表示數據。這就引出一個問題。

多字節數據怎麽存儲?字節的排列順序?

  在幾乎所有的機器中,多字節數據都是被存儲為連續的字節序列,數據的地址為所使用字節中最小的地址。

  多字節數據還存在另一個問題:字節的排列問題。通常數據的字節排列有兩個通用的規則:大端法(big endian)和小端法(little endian)

  下面以0x12345678為例說明這個4字節數據在內存中的存儲方式:

字節存儲
內存地址 -> 0x1(最小存儲地址) 0x2 0x3 0x4
大端法 -> 12(最高有效字節) 34 56 78
小端法 -> 78(最低有效字節 56 34 12

  可見,大端法和小端法是相反的。大端法最高有效字節在前,小端法最低有效字節在前。下面用C語言測試當前運行的系統是采用哪種存儲方式。

#include <stdio.h>
void showByte() {
    int num = 0x12345678;
    char* cp = (char*) &p;
    
for(int i = 0; i < sizeof(int); i++) {
     if(0x78 == *cp) printf("小端法: ");
     else printf("大端法: "); printf(
"0x%x ", *cp); // 輸出:0x78 0x56 0x34 0x12 因此是小端法存儲。 cp++; } } int main() { showByte(); }

C語言中的目標文件中沒有數據類型,那CPU如何知道在內存讀取多字節數據呢?

 根據上面的showByte函數生成的匯編代碼知,每條數據操作指令都帶有操作數的字節大小,如第14行的movq -8(%rbp), %rax 表示要往內存地址-8(%rbp)中讀取4個字節到%rax寄存器。CPU通過指令知道讀取多字節數據。

 showByte:
 1     pushq   %rbp
 2     .seh_pushreg    %rbp
 3     movq    %rsp, %rbp
 4     .seh_setframe   %rbp, 0
 5     subq    $48, %rsp
 6     .seh_stackalloc 48
 7     .seh_endprologue
 8     movl    $305419896, -16(%rbp)
 9     leaq    -16(%rbp), %rax
 10     movq    %rax, -8(%rbp)
 11     movl    $0, -12(%rbp)
 12     jmp .L2
 13 .L3:
 14     movq    -8(%rbp), %rax
 15     movzbl  (%rax), %eax
 16     movsbl  %al, %eax
 17     movl    %eax, %edx
 18     leaq    .LC0(%rip), %rcx
 19     call    printf
 20     addl    $1, -12(%rbp)
 21     addq    $1, -8(%rbp)
 22 .L2:
 23     movl    -12(%rbp), %eax
 24     cmpl    $3, %eax
 25     jbe .L3
 26     nop
 27     addq    $48, %rsp
 28     popq    %rbp
 29     ret

參考文獻:

  《深入理解計算機系統》第三版

字節與小端、大端法存儲。