深入了解计算机系统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 访问条件码
条件码通常不会直接读取,常用的使用方法有三种
- 根据条件码的某种组合将一个字节设置为0或者1,这一整类指令称之为SET指令,具体其情况看表3-14。
- 可以条件跳转到程序的某个部分,这一整类指令称之为Jcc指令,比如jg、jl、ja等。
- 可以有条件的传输数据。例如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/