CSAPP学习笔记(2)

随便说说

看着老师按照一个个汇编语言的顺序来讲解,感觉自己的计算机学习的前途一片黯然

上课影响学习,不要怀疑自己

程序的机器及表示

编译过程

首先我们来复习一下一个高级语言程序在计算机中是如何被编译的。

举个栗子

我们直接来看一段代码和其编译出来的汇编代码

1
2
3
4
5
long mult2(long, long);
void multstore(long x, long y, long *dest) {
long t = mult2(x, y);
*dest = t;
}
1
2
3
4
5
6
7
multstore:
pushq %rbx
movq %rdx,%rbx
call mult2
movq %rax,(%rbx)
popq %rbx
ret

看不懂也无所谓,我们只需要像小学生一样观察一下下面汇编语言的格式和特点就好。

稍微观察便可以知道,下面代码的格式均为 一个操作指令 后面跟着 1/2/3 个操作数

为什么是以这样的形式呢?其实是取决于处理器的运算方式。

1742180279192

  • 程序计数器(PC, Program counter) - 存着下一条指令的地址,在 x86-64 中称为 RIP
  • 寄存器(Register) - 用来存储数据以便操作
  • 条件代码(Codition codes) - 通常保存最近的算术或逻辑操作的信息,用来做条件跳转

这里需要注意,处理器能够执行的操作其实是非常有限的,简单来说只有三种:存取数据、计算和传输控制。存取数据是在内存和寄存器之间传输数据,进行计算则是对寄存器或者内存中的数据执行算术运算,传输控制主要指非条件跳转和条件分支。这也就是为什么汇编代码有固定的 指令 操作数1 (,操作数2 ,操作数3) 这样的形式了。

再举一个具体的例子

1
2
3
4
5
6
7
8
// C 代码
*dest = t;

// 对应的汇编代码
movq %rax, (%rbx)

// 对应的对象代码
0x40059e: 46 89 03

C 代码的意思很简单,就是把值 t 存储到指针 dest 指向的内存中。对应到汇编代码,就是把 8字节(也就是四个字, Quad words)移动到内存中(这也就是为什叫做 movq)。t 的值保存在寄存器 %rax 中,dest 指向的地址保存在 %rbx 中,而 *dest 是取地址操作,对应于在内存中找到对应的值,也就是 M[%rbx],在汇编代码中用小括号表示取地址,即 (%rbx)。最后转换成 3 个字节的指令,并保存在 0x40059e 这个地址中。

参考文献(巨佬 Orz)注:本文有部分内容是直接复制来源于原文,目的仅用于学习