30

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

4

6 回答 6

44

区别在于使用哪些指令来操作数据,而不是数据本身。现代计算机(大约从 1970 年开始)使用称为二进制补码的整数数据表示,其中加法和减法在有符号和无符号数上的工作方式完全相同。

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

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

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

  • CF(进位标志)表明一个位是否完全从字中取出(例如进入第 33 位或第 65 位)。如果数字被解释为无符号,进位标志意味着加法溢出,结果太大而无法放入机器字中。溢出标志无关紧要。

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

  • 它可以选择 CF 或 OF 进行有符号或无符号比较。
  • 它可以选择有符号或无符号乘除法指令。
  • 它可以选择有符号或无符号右移(有符号复制高位;无符号移位为零)。
于 2009-04-27T01:53:59.937 回答
19

不要尝试对标志进行操作编码。那是不可能的。相反,只尝试去了解真相:没有迹象。然后你会发现区分的不是符号类型,而是你自己。

于 2009-04-27T02:43:16.900 回答
6

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

类似地,还有一些setCC指令,根据比较将一个字节设置为 0 或 1。这些功能相同 - 有setl, setle, setg, setge, setb, setbe, seta, setae, 等。

签名的操作码测试标志 ZF、OF 和 SF。无符号操作码测试标志 ZF、CF 和 SF。请参阅 80386 程序员参考手册中有关JCC指令和setCC指令的部分,了解测试的确切条件。

于 2009-04-27T01:59:43.633 回答
4

它没有。只要条件发生,标志就会被设置。程序员应该知道他正在使用哪些类型的 int,并从中知道他是否关心要检查哪个标志。

于 2009-04-27T01:48:18.343 回答
3

没有办法要求 CPU 测试并返回一个字节/字/长的类型。

0xFF 可能包含“255”或“-1”,这完全取决于您的程序所说的字节类型。

“type”、“signess”等结构仅存在于 Java 等高级语言中,而不存在于 CPU 级别。最后,一切对 CPU 来说都是一个字节,这取决于我们的程序来组织和知道如何解释和操作这些值......

在状态中找到的 CPU 标志不会强制执行任何范例,这取决于您的代码进行测试并做出相应的反应。

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

于 2009-04-27T02:38:28.830 回答
1

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

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

于 2009-04-27T01:47:01.903 回答