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


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

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

    参考文献:

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

  • 相关阅读:
    LAMP LNMP 和 LNMPA
    nginx版本如何选择?
    如何看apache的版本号
    CLR Via CSharp读书笔记(12):泛型
    要先怀疑外部代码的错误,再检测是不是自己代码的问题
    redis的那些事
    An Illustrated Guide to SSH Agent Forwarding
    Using sshagent with ssh
    dtach
    [原创]bind DNS IP列表的精确获取
  • 原文地址:https://www.cnblogs.com/yvkm/p/10398527.html
Copyright © 2020-2023  润新知