Renyddd Site
Created: 27 Nov 2022

Representing Memory Object

Representing 字节表示

参考《深入理解计算机系统》中文第三版 P31 页例程,来打印 不同程序对象的字节表示:

#include <stdio.h>
#include <string.h>

typedef unsigned char *byte_pointer;

void show_bytes(byte_pointer start, size_t len) {
  size_t i;
  for (i = 0; i < len; i++) {
    printf(" %.2x", start[i]);
  }
  printf("\n");
}

void show_int(int x) { show_bytes((byte_pointer)&x, sizeof(int)); }

void show_float(float x) { show_bytes((byte_pointer)&x, sizeof(float)); }

void show_pointer(void *x) { show_bytes((byte_pointer)&x, sizeof(void *)); }

void test_show_bytes(int val) {
  int ival = val;
  float fval = (float) ival;
  int * pval = &ival;
  show_int(ival);
  show_float(fval);
  show_pointer(pval);
}

int main() {
  test_show_bytes(12345);
}

39 30 0 0        
0 e4 40 46        
a8 c5 de be f7 7f 0 0

首先仅解释小端机器(Linux、MacOS)上的输出结果:

  1. 本机为小端法(little endian);
  2. 本机为 64 位机;

字节地址

大多数计算机使用 8 位的块,也称为 字节 Byte 来作为最小的可寻址的内存单位。

机器级程序将内存视为一个非常大的 字节数组 ,称为 虚拟内存 virtual memory, 内存中的每个字节都由一个唯一的数字来标识,称为它的 地址 address.

字长 word size 用以指明指针数据的 标称大小 nominal size, 因为虚拟地址是以这样的一个字来编码的,所以字长决定虚拟地址空间的最大大小:

  • 当前存在从 32 位字长机器到 64 位字长机器的迁移;
  • 对于字长为 w 位的机器,其虚拟地址范围为 0 ~ 2w - 1;
  • 程序最多访问 2w 个字节;

二进制与十六进制 Binary and Hexadecimal

补充一点自己当前的理解,二进制可完全表示当前内存比特位,而十六进制的设计是便于与二进制转化并节省展示空间。 如上流程输出结果中的 39 30 0 0 可直接将每个数字展开为二进制: 00111001 10110000 00000000 00000000

大端小端

对于跨越多字节的程序对象,我们必须清楚,在内存中如何排列这些字节。

假设将一个 4*8 位的整数 x 按照 8 位(字节)分组,其中最高有效字节包含位 [x31, x30, …, x24],最低有效字节为 [x7, x6, …, x0]。

  • 如果有的机器选择在内存中按照从最低有效字节到最高有效字节顺序存储对象,则称为 小端法 little endian;
  • 按照从最高有效字节到最低有效字节的顺序存储,则称为 大端法 big endian;
    • 这是人类读写数值的方式。

引用 CSAPP 书中的例子:

假设变量 x 的类型为 int,位于地址 0x100 处,它的十六进制值为 0x1234567。 地址范围 0x100 ~ 0x103 的字节顺序依赖于机器的类型:

  • 大端法: 01 23 45 67
  • 小端法: 67 45 23 01
Creative Commons License
renyddd by Renyddd is licensed under a Creative Commons Attribution-ShareAlike 3.0 Unported License.