字节与小端、大端法存储。

以下仅为个人学习的记录,如有疏漏不妥之处,还请不吝赐教

字节(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

参考文献:

  《深入理解计算机系统》第三版

posted @ 2019-02-19 00:06  yvkm  阅读(1118)  评论(0编辑  收藏  举报