机器级程序的小细节

    随着技术的逐渐发展,CPU 中晶体管的数量以每年 37% 的速度递增,CPU 也从 16 位到了 32 位,现在已经到了 64 位,为了保证以前编译的程序仍然能够在最新的机器上使用,所以寄存器保留了原来的命名。

    比如一个 16 位的寄存器有自己的名字,当扩展成 32 位的时候,会保留原来 16 位寄存器的名字,并给整个 32 位寄存器取一个新的名字。如同“天生我材必有用”,每个寄存器都有它自己独有的舞台。

image

    最开始的 16 位称之为“字(word)”,用于表示 16 位数据类型,扩展后的 32 位和 64 位分别称为“双字(double words)”和“四字(quad words)”。

    汇编代码最接近机器代码,它不像高级语言屏蔽了很多实现的细节,比如区分不同字长的数据,汇编语言采用的方式是给汇编指令添加后缀(大多数情况下可以省略),即用后缀来指定操作数的大小,和寄存器一一对应。

image

    机器级程序使用的内存地址是虚拟地址,在机器级程序的眼里,内存就是一个非常大的字节数组,而我们运行的程序就放在内存中。程序在机器眼里就是一段字节序列。

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

    将这一段汇编语言代码转换成目标文件,因为目标文件时二进制格式的,我们无法查看,如果以 16 进制表示上述汇编代码,将是53 48 89 d3 e8 00 00 00 00 48 89 03 5b c3这样的字节序列。

    高级语言提供了面向对象的概念,C 语言也提供了数组和结构体这样的聚合数据类型,但是这所有的概念在机器级程序中都是不存在的,汇编代码不区分有符号或无符号整数,也不区分不同数据类型的指针,甚至连指针和整数都不进行区分。

    程序运行时是把指令序列放到内存中去,但是比如条件分支指令等情况会造成跳转,使得指令地址变得不连续,有个 PC(程序计数器)就专职负责给出下一条指令的地址,这个 PC 的重要程度不言而喻。

    虽然我们觉得机器级程序编程已经很底层了,是上个世纪使用纸带穿孔编程序的操作,但实际上机器级程序已经在硬件基础上进行了一个层次的抽象,机器级程序的格式和行为是指令集体系结构或指令集架构来定义的。

    X86-64 的指令长度从 1 字节到 15 字节不等。不用多说,肯定是常用的指令所需要的字节更少,而那些不常用或者操作数较多的指令就需要更多的字节。

    设计指令的方式是从某个位置开始,可以将字节唯一地解码成机器指令。比如,只有指令pushq %rbx是以字节值 53 开头的。

    本以为第二章看起来就很枯燥了,没想到第三章开起来更加枯燥,但是也越来越体会到抽象在计算机科学中的地位。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Guanngxu

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值