CSAPP读书笔记——程序的机器级表示之条件跳转与循环

本文介绍了CSAPP中程序的机器级表示,涉及条件分支(如if、switch)和循环(do-while,while,for)的机器表示。通过条件码、cmp指令、set指令实现条件判断,结合跳转指令(如jmp)实现程序流程控制。此外,还探讨了循环的机器实现,包括do-while、while和for循环的转换,并讲解了switch语句的跳转表实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

程序控制指令


上一章节讲到的是数据的移动、计算的底层代码表示,其中,每条汇编指令都是顺序执行的。考虑C语言中三种程序执行方式。

顺序、条件、循环。

本章简练介绍条件分支(if、switch)和循环(do-while,while,for)的机器级表示。


条件分支


条件分支指代单条件分支。程序通过测定某些条件的成立与否,控制程序的走向。反映到C语言当中,即 ifelse 语句。
除了整型寄存器之外,CPU还会跟踪一个条件码寄存器。某一个条件码只用一个bit来表示,代表某种状态。这些状态可以被测试从而决定是否更改程序的走向,从而达到条件分支的效果。

条件码


  • CF(carry flag) : 进位标志。最近的操作产生最有效位进位时,设置为true。可以用来检查无符号整数是否溢出。
  • ZF(zero flag) : 零标志。最近的操作产生的结果为0时,设置为true。
  • SF(sign flag) : 符号标志。最近的操作产生的结果为负数时,设置为true。
  • OF(overflow flag):溢出标记。(补码)最近的操作产生的结果导致溢出(正溢出或者负溢出)时,设置为true。显然用来检测有符号整数是否溢出。

注意,这里标注了说是最近的操作,也就是说,只要进行了数据的计算,条件码都会发生改变(leal除外,因为它不仅仅是用地址进行计算)。

所以说,条件码会不断的发生变化。


cmp指令集合


当有了条件码的时候,计算机就可以根据条件码的状态执行比较和测试指令

指令 基于 描述
cmp S2,S1 S1S2 比较 S1,S2
cmpb compare byte
cmpw compare word
cmpl compare double word
test S2,S1 S1 & S2 测试
testb test byte
testw test word
testl test double word
  • cmp 命令基于 sub 命令, sub 在上一章数据计算中已经解释过。不同于 sub , cmp 仅仅是将 s2,s1 中的数据拿出来做了计算,但是并没有改变 s2,s1 中的任意一个寄存器的状态,它们的值是始终保持不变的。
  • test 命令是测试,基于命令 and ,基于的意思即不会改变寄存器的状态。它的重要用途是检测某寄存器的数值是0、正数、负数,或者其中一个操作数当做掩码,指示那些位置应当被测试。

set指令集


cmp 指令集的作用类似于数据计算指令集,可以更改条件码的状态。那么当我们有了条件码的状态的时候,我们如何去访问或者获得条件码呢?
条件码不可以被直接访问,通常来讲有三种方法获取条件码。

  1. 根据条件码的组合将某bit设置为0,1。作为条件分支检测的方式,相当于间接访问了条件码。
  2. 利用条件码,我们可以跳转到程序的某个分支,也相当于间接访问条件码并且改变了控制流。
  3. 类似于2,我们可以通过条件检测有条件的传输数据流。

对于第一种方法,不同的条件码的组合设定某个bit为0或者1等,这样的操作cpu集成了 set 指令。

指令 同义指令 效果 设置条件
sete D setz ZF-> D 相等/零
setne D setnz ~ZF-> D 不等/非零
sets D
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值