数据传送指令:
MOV指令:将数据从源位置复制到目的位置,不做任何变化;MOV指令由四条指令组成:movb、movw、movl、movq;它们的区别在于它们操作的数据大小不同,分别为1、2、4、8字节;
压入和弹出栈数据:
遵循“后进先出”原则,通过push操作将数据压入栈中,通过pop操作删除数据;弹出的值,永远是最近被压入而且仍然在栈中的值。其中,栈顶元素的地址是所有栈中元素地址最低的。将一个四字值压入到栈中,首先要将栈指针减8,然后将值写入到新的栈顶指针。因此,指令pushq %rbp的行为等价于:
sub $8,%rsp
movq %rbp,(%rsp)
弹出一个四字的操作包括从栈顶位置读出数据,然后将栈指针加8。因此,指令popq %rax等价于下面两条指令:
movq (%rap),%rax
addq &8,%rsp
算术和逻辑运算:
下图列出了一些整数和逻辑操作。给出的每个指令类都有对这四种不同大小数据的指令。这些操作被分为四组:加载有效地址,一元操作,二元操作和移位;
加载有效地址leaq实际上是对movq指令的变形。它的指令形式是从内存读数据到寄存器,但实际上它根本就没有引用内存。
一元操作:只有一个操作数,既是源,又是目的。如,incq(%rsp)会使栈顶的8字节元素加1。
二元操作:第二个操作数既是源,又是目的。如 subq %rax,%rdx,它表示寄存器%rdx的值减去%rax中的值。
控制:jump指令可以改变一组机器代码指令的执行顺序;
条件码:
CF:进位标志;
ZF:零标志;
SF:符号标志;
OF:溢出标志;
实现条件操作的传统方法是,通过使用控制的条件转移。当条件满足时,程序沿着一条执行路径执行,而当条件不满足时,就走另一个条路径。这种机制简单通用,但是在处理器上它可能低效;
一种替代的策略实使用数据的条件转移。这种方法计算一个条件操作的两种结果,然后再根据条件是否满足从中选取一个。
循环:汇编中是没有相应的循环指令,但是可以用条件指令和跳转组合起来实现循环的效果;
如:
对应:
switch语句:执行switch语句的关键步骤是通过跳转表来访问代码位置;
图3-23则是编译switch_eg时产生的汇编代码:
过程:
过程是软件中一种很重要的抽象,过程的形式多样:函数、方法、子例程、处理函数等等;
要提供对过程的机器级支持,必须要处理许多不同的属性。假设过程P调用过程Q,Q执行后返回到P。这些动作包括下面一个或多个机制:
传递控制、传递数据、分配和释放内存;
运行时栈:先进后出的内存管理原则。
以上,过程P在调用过程Q。当Q在执行时,P以及所有在向上追溯到P的调用链中的过程,都是暂时被挂起的。当Q运行时,它只需要为局部变量分配新的存储空间,或者设置到另一个过程的调用。另一方面,当Q返回时,任何它所分配的局部存储空间都可以被释放。因此,程序可以用栈来管理它的过程所需要的存储空间,栈和程序寄存器存放着传递控制的数据、分配内存所需要的信息。当P调用Q时,控制和数据信息添加到栈尾。