csapp第三章 程序的机器级表示(3)

总结:

​ 第三章总的来说,可以说是简要的说明了汇编语言的一些细节

之前学校有开设汇编语言的课程,只是那时的自己还处在懵逼的时代,感觉这种底层的知识离我很遥远,但是当我渐渐改变,迷迷糊糊的看完csapp第三章后,也能得到一些感慨: 那就随便说说吧!

感慨

先看一个c语言代码

1
2
3
4
5
int sum(int x,int y)
{
int t=x+y;
return t;
}

生成汇编代码

1
2
3
movl (%ebp),%eax  从内存中得到x放入eax寄存器
movl 4(%ebp),%edx 从内存中得到y 放入edx寄存器
addl %edx,%eax 将x和y相加

以IA32来说明:

​ mov 是移动,将%ebp 移动到%eax 后面的l是区分不同的数据类型的 char int double 这些类型,l就是为了区别它们 这个指令将一个地址里面的数移动到另一个地方,也就想当于赋值 。

想想:我们将一个短数据放入长数据位置会怎么样?

一个char放入一个int的空间,会剩下8位空的,那么需要使用movsbl(符号拓展)和movzbl(0拓展)这两个指令 c语言中的有符号无符号之间的运算,便需要借助这些指令。

操作数指示符

c语言具有不同的数据类型,汇编也一样:

​ 立即数类型, 也就是常数,在程序中我们会常常用到常数,在ATT表示下是一个常数前面加上$。

​ 寄存器类型,CPU中,有一个寄存器文件,寄存器类型就是指寄存器文件中某个寄存器中的内容。

​ 存储器引用,存储器指我们的内存区,内存相当于一个大型的字节数组,这里的存储器引用就是指这个数组的索引(数组的下标)

常见指令

书中讲解的比较详细;这里挑一个出来说明

1
2
3
4
5
6
7
int choose(int x,int y)
{
if(x<y)
return y-x;
else
return x-y;
}
1
2
3
4
5
6
7
8
9
10
movl 8(%ebp),%edx   x在%ebp+8处
movl 12(%ebp),%eax y在%ebp+12处
cmpl %eax,%edx
jge .L2
subl %edx,%eax
jmp .L3
.L2:
subl %eax,%edx
movl %edx,%eax
.L3:

第三条指令就是比较指令, 可以发现:每条比较指令下面跟着一条跳转语句,执行完比较操作后,相应的标志位会置位。