深入了解计算机系统3.6.1-3.6.2

3.6.1 条件码

常用条件码

  • CF:carry flag 进位标志。可用于检查是否溢出。可用来检查无符号操作的溢出。
  • ZF:zero flag 零标志。最近操作得出的结果为0。
  • SF:sign flag 符号标志。最近的操作得到的结果为负数。
  • OF:overflow flag 溢出标志。最近的操作导致一个补码溢出。

这里CF和OF要注意下,在汇编中并没有数据类型来区分一个数是有符号还无符号,所以需要根据上下文和对数据的预期用途来决定是检查CF还是OF。举一个极端的例子,10000000+11111111在有符号的情况下是-128+-1=-129,这不仅超出了有符号8位数范围导致OF被设置为true,而且从无符号的角度来看,这两个数是128+255=383,也超过了无符号8位的最大值,导致CF也被设置为true。

算数和逻辑操作都会设置条件码,XOR进位标志和溢出标志会设置成0。位移操作会将进位标志设置为最后一个被移出的位,而溢出标志则会被设置为0。INC和DEC指令会设置溢出和零标志,但是不会改变进位标志。除了以上两种还有比较(cmp)和测试(test)指令,他们只设置条件码而不修改寄存器的值。

3.6.2 访问条件码

条件码通常不会直接读取,常用的使用方法有三种

  1. 根据条件码的某种组合将一个字节设置为0或者1,这一整类指令称之为SET指令,具体其情况看表3-14。
  2. 可以条件跳转到程序的某个部分,这一整类指令称之为Jcc指令,比如jg、jl、ja等。
  3. 可以有条件的传输数据。例如cmovl %eax,%ebx;如果%eax小于%ebx(SF≠OF),则将%ebx的值传给ESI。
指令 同义名 效果 设置条件
sete D setz D <- ZF 相等/零
setne D setnz D <- ~ZF 不等/非零
sets D D <- SF 负数
setns D D <- ~SF 非负数
setg D setnle D <- ~(SF^OF)&~ZF 大于(有符号>)
setge D setnl d <- ~(SF^OF) 大于等于(有符号>=)
……

使用set指令时,操作数只能为8位寄存器%al、%bl等,或者内存中的一个字节码。当把结果转入%eax之类的寄存器时,需要清空高位内容,例子 setl %al;movbl %al,%eax;。


深入了解计算机系统3.6.1-3.6.2
https://biqibao.cn/2025/03/25/深入了解计算机系统3-6-1_3-6-2/
作者
Ye
发布于
2025年3月25日
许可协议