【发布时间】:2009-04-27 01:34:49
【问题描述】:
众所周知,CF 表示无符号进位,OF 表示有符号溢出。那么汇编程序如何区分无符号和有符号数据,因为它只是一个位序列? (通过额外的内存存储类型信息,或通过位置信息或其他方式?)这两个标志可以互换使用吗?
【问题讨论】:
众所周知,CF 表示无符号进位,OF 表示有符号溢出。那么汇编程序如何区分无符号和有符号数据,因为它只是一个位序列? (通过额外的内存存储类型信息,或通过位置信息或其他方式?)这两个标志可以互换使用吗?
【问题讨论】:
区别在于使用哪些指令来操作数据,而不是数据本身。现代计算机(大约从 1970 年开始)使用称为二进制补码的整数数据表示,其中加法和减法在有符号和无符号数上的工作方式完全相同。
表示的不同之处在于对最高有效位(也称为符号位)的解释。对于无符号数,当数字处于完全正范围的上半部分时,设置最高有效位。对于有符号数字,当数字在整个范围的下半部分和负半部分时,设置最高有效位。
不同的指令可能对同一位使用不同的解释。例如,大多数大型机器都有有符号和无符号乘法指令。带有“set less than”指令的机器可能同时具有签名和未签名的风格。
OF(溢出标志)表明进位是否翻转了结果中最高有效位的符号,使其与参数的最高有效位不同。如果将数字解释为无符号,则溢出标志无关紧要,但如果将它们解释为有符号,则 OF 表示,例如,将两个大的正数相加,结果为负。
CF(进位标志)表明一个位是否完全从字中执行(例如,进入位 33 或位 65)。如果数字被解释为无符号,进位标志意味着加法溢出,结果太大而无法放入机器字中。溢出标志无关紧要。
您的问题的答案是汇编代码有几种区分有符号数据和无符号数据的方法:
【讨论】:
不要尝试对标志进行操作码。那是不可能的。相反,只尝试去了解真相:没有迹象。然后你会发现区分的不是符号类型,而是你自己。
【讨论】:
处理有符号和无符号数据有不同的操作码。如果程序想要比较两个有符号整数,它使用操作码jl、jle、jg 和jge,其中 l 和 g 代表 less 和 great 分别。如果一个程序想要比较两个无符号整数,它使用操作码jb、jbe、ja和jae,其中a和b分别代表above和b分别低于。在所有情况下,e 都代表“或等于”。这些操作码用于根据比较进行分支。
同样,还有setCC 指令,根据比较将字节设置为0 或1。这些功能相同——有setl、setle、setg、setge、setb、setbe、seta、setae等。
签名的操作码测试标志 ZF、OF 和 SF。无符号操作码测试标志 ZF、CF 和 SF。有关测试的确切条件,请参阅 80386 程序员参考手册中的 JCC 指令和 setCC 指令部分。
【讨论】:
它没有。只要条件发生,标志就会被设置。程序员应该知道他正在使用哪些类型的 int,并从中知道如果他关心要检查哪个标志。
【讨论】:
没有办法要求 CPU 测试并返回一个字节/字/长的类型。
0xFF 可能包含“255”或“-1”,这完全取决于您的程序所说的字节类型。
诸如“类型”、“符号”等结构仅存在于 Java 等高级语言中,而不存在于 CPU 级别。最后,一切对 CPU 来说都是一个字节,这取决于我们的程序来组织和了解如何解释和操作这些值......
在状态中找到的 CPU 标志不会强制执行任何范例,这取决于您的代码进行测试和做出相应反应。
在 Intel CPU 上,MMX 和 FPU 寄存器实际上占用相同的寄存器。因此不可能同时混合 FPU 和 MMX 类型的指令,因为来自一个操作的值会破坏另一个操作。需要任一模式的程序通常以一种模式完成其操作,例如发出 FPU 指令,然后可能会启动 MMX,但绝不会同时启动这两种模式。
【讨论】:
通常汇编程序不带变量的特殊信息来指示它们是有符号还是无符号。程序员的工作是知道何时检查哪些标志以及何时使用哪些条件(即使用 JA 而不是 JG)。
因此,您需要知道要使用的变量类型,以便知道要使用哪些命令。这就是为什么大多数编程语言在程序员交替使用有符号/无符号类型(即没有显式转换)时会发出警告,因为这可以在硬件中完成,但会产生意想不到的结果。
【讨论】: