关于装配CF(Carry)和OF(溢出)标志

时间:2009-04-27 01:34:50

标签: assembly x86 flags

已知CF表示无符号执行,OF表示有符号溢出。那么汇编程序如何区分无符号和有符号数据,因为它只是一个位序列? (通过额外的存储器存储类型信息,或通过位置信息或其他?)这两个标志可以互换使用吗?

6 个答案:

答案 0 :(得分:35)

区别在于使用什么指令来操纵数据,而不是数据本身。现代计算机(自1970年左右开始)使用称为二进制补码的整数数据表示,其中加法和减法在有符号和无符号数上完全相同。

  • 表示的差异是对最高有效位(也称为符号位)的解释。对于无符号数,当数字位于完全正范围的上半部分时,设置最高有效位。对于带符号的数字,当数字在整个范围的下半部分和负半部分时,最高有效位被设置。

  • 不同的指令可能使用相同位的不同解释。例如,大多数大型机器都有签名和无符号乘法指令。 “set小于”指令的机器可能具有有符号和无符号的风格。

  • OF(溢出标志)告诉进位是否翻转了结果中最高有效位的符号,使其与参数的最高有效位不同。如果数字被解释为无符号,则溢出标志是无关紧要的,但如果它们被解释为有符号,OF意味着,例如,添加了两个大的正数,结果是负数。

  • CF(进位标志)指示是否完全执行了该位(例如,进入位33或位65)。如果数字被解释为无符号,则进位标志表示加法溢出,结果太大而无法放入机器字中。溢出标志无关紧要。

您的问题的答案是汇编代码有多种方法可以区分有符号数据和无符号数据:

  • 可以选择CF或OF进行签名或未签名的比较。
  • 它可以选择有符号或无符号乘法和除法指令。
  • 它可以选择有符号或无符号右移(有符号复制高位;无符号移位为零)。

答案 1 :(得分:17)

不要尝试操作符号。那是不可能的。相反,只是试图实现真相:没有迹象。然后你会发现它不是区分的标志类型,只有你自己。

答案 2 :(得分:5)

处理有符号和无符号数据有不同的操作码。如果程序想要比较两个有符号整数,它会使用操作码jljlejgjge,其中l和g代表 l分别是 ess和 g reater。如果程序想要比较两个无符号整数,它会使用操作码jbjbejajae,其中a和b代表 a bove和 b 分别为elow。在所有情况下,e代表“或等于”。这些操作码用于基于比较的分支。

同样,还有setCC指令,根据比较将字节设置为0或1。这些功能相同 - 有setlsetlesetgsetgesetbsetbeseta,{ {1}}和其他人。

签名的操作码测试标志ZF,OF和SF。无符号操作码测试标志ZF,CF和SF。有关所有测试条件的详细信息,请参阅JCC说明中的80386程序员参考手册部分和setCC说明。

答案 3 :(得分:4)

没有。只要条件发生,标志就会置位。程序员应该知道他正在使用什么类型的int,以及知道他要关注哪个标志。

答案 4 :(得分:3)

无法要求CPU测试并返回字节/字/长的类型。

0xFF可以保持“255”或“-1”,这取决于程序所说的字节类型。

诸如“type”,“signess”等构造仅存在于诸如Java之类的更高级语言中而不存在于CPU级别。最后,一切都是CPU的一个字节,由我们的程序组织并知道如何对这些值进行整理和操作......

状态中找到的CPU标记不强制执行任何范例,由您的代码进行测试并做出相应的反应。

在Intel CPU上,MMX和FPU寄存器实际上占用相同的寄存器。因此,不可能同时混合FPU和MMX类型的指令,因为来自一个操作的值将使另一个操作混乱。需要的程序通常在一种模式下完成其操作,例如发出FPU指令,然后可能启动MMX,但不能同时启动MMX。

答案 5 :(得分:1)

通常,汇编程序不附带变量的特殊信息,以指示它们是已签名还是未签名。程序员的工作是知道何时检查哪些标志以及何时使用哪些条件(即使用JA而不是JG)。

因此,您需要知道要使用的变量类型,以便了解要使用的命令。这就是为什么大多数编程语言在程序员可以互换地使用有符号/无符号类型时(即没有显式强制转换)发出警告的原因,因为这可以在硬件中完成,但会产生意想不到的结果。