3.6.1 条件码
- 除了整数寄存器,CPU还维护着一组单个位的条件码寄存器,它们描述了最近的算术或逻辑操作的属性,可以检测这些寄存器来执行条件分支指令。
-
常用条件码
- 除了leaq以外,所有算术和逻辑操作指令都会设置条件码。
- cmp和test指令只改变条件码寄存器,cmp等同于sub,test等同于and,只不过它们只设置条件码寄存器。
3.6.2 访问条件码
set指令,目的操作数是单字节寄存器或一个字节的内存位置,将这个字节设置成0或1。执行过程是执行比较指令,根据计算t=a-b设置条件码。
3.6.3 跳转指令
跳转jump指令会导致执行切换到程序中一个全新的位置,跳转的目的地通常用一个标号label表明,也可以从寄存器或内存读出。
3.6.4 跳转指令的编码
跳转指令常用的两种编码:一是将目标指令与跳转指令后面那条指令的地址之差作为编码;二是用四个字节直接指出目标。
3.6.5 用条件控制来实现条件分支
if else风格的c语言代码,转化为汇编时通常会通过条件控制结果jmp跳转来实现。
3.6.6 用跳转传送来实现条件分支
- 指令名:cmov
- 条件控制依赖条件预测,如果预测结果随机,预测失败重新计算的代价很大。
- 条件转移并不总是比条件控制效率高,比如需要计算的开销非常大的情况。
3.6.7 循环
-
do-while循环,汇编中通过跳转jmp(jg)到上面的label实现
-
while循环有两种翻译方法,第一种被称为跳转到中间
第二种被称为guarded-do,首先用条件分支,如果初始条件不成立就跳过循环,把代码变换为do-while循环。
- for循环,GCC根据编译的优化等级为for循环选择while的两种翻译方法之一。
3.6.8 switch语句
汇编代码会使用一种跳转表的方法来优化switch
3.6.9 逆向工程
根据汇编代码反推出应用程序的源代码,关键是找到程序值和寄存器之间的映射关系。