计算机系统3.1, 3.2, 3.3
计算机系统3.1, 3.2, 3.3

计算机系统3.1, 3.2, 3.3

程序的机器级表示

历史观点

SSE – 这是一类处理整数或浮点数向量的指令.

AVX 支持把数据封装进256位的向量.

一些通常对C语言程序员隐藏的处理器状态都是可见的

  • 程序计数器(通常称为"PC", 在x86-64中用%rip表示)给出将要执行的下一条指令在内存中的地址.
  • 整数寄存器文件包含16个命名的位置, 分别存储64位的值. 这些寄存器可以存储地址或整数数据. 有的寄存器用来保存临时数据, 例如过程的参数和局部变量, 以及函数的返回值.
  • 条件码寄存器保存着最近执行的算术或逻辑指令的状态信息. 它们用来实现控制或数据流中的条件变化, 比如说用来实现if和while语句.
  • 一组向量寄存器可以存放一个或多个整数或浮点数值.

x86-64的虚拟地址是由64位的字来表示的, 在目前的实现中, 这些地址的高十六位必须设置为0

为什么呢?

对于48位的内存地址, 内部机制已经多层嵌套, 复杂度已经很高.

48位已经可以支持64TB的内存,目前来说够用。
因为64机可供系统使用的线性地址空间太大,目前内存的容量还没有达到2的64次幂,没有必要使用全部的64位。48位的虚拟地址转换成物理地址需要4级页表,在tlb缺失时访存次数已经比32位时多了两次,虽然现在的处理器也有高层页表的缓存。如果在没有需求的情况下用满64位,浪费了空间,也增加了转换的访存次数。另外现在Intel已经发布了57位寻址方案的白皮书了。

操作系统和虚拟地址

操作系统负责管理虚拟地址空间, 将虚拟地址翻译成实际处理器内存中的物理地址.

程序编码

使用Unix命令行编译代码并形成机器及代码:

linux> gcc -Og -o p p1.c p2.c

命令gcc为gcc编译器, 它的别名是cc.

编译选项-Og告诉编译器使用会生成符合原始C代码整体结构的机器代码的优化等级. 而-O1, -02为较高级别的优化.

-o p指定产生最终的可执行代码文件p.

代码示例

long mult2(long, long);

void multstore(long x,long y, long *dest){
    long t = mult2(x,y);
    *dest =t;
}

在命令行上使用-S选项, 就能看到C语言编译器产生的汇编代码:

linux> gcc -Og S mstore.c

产生的汇编文件mstore.s的一部分代码如下:

multstore:
  pushq     %rbx
  movq      %rdx, %rbx
  call      mult2
  movq      %rax, (%rbx)
  popq      %rbx
  ret

代码中的每一个缩进行都代表了一条机器指令, 比如pushq指令表示应该将寄存器%rbx的内容压入程序栈中.

如果我们使用-c选项, gcc就会编译并汇编该代码并产生目标代码文件mstore.o.

结果如下:

关于格式的注解

如下文件mstore.s

    .file   "010-mstore.c"
    .text
    .globl  multstore
    .type   multstore, @function
multstore:
    pushq   %rbx
    movq    %rdx, %rbx
    call    mult2
    movq    %rax, (%rbx)
    popq    %rbx
    ret
    .size   multstore, -multstore
    .ident  "GCC: (Ubuntu 4.8.1-2ubuntu1~12.04) 4.8.1"
    .section    .note.GNU-stack,"",@progbits

所有以"."开头的行都是指导汇编器和链接器工作的伪指令.

数据格式

浮点数的后缀和整数后缀相同不会产生歧义, 因为浮点数使用的是一组完全不同的指令和寄存器.

发表回复

您的电子邮箱地址不会被公开。

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据