c - c编译器如何处理无符号和有符号整数?为什么无符号和有符号算术运算的汇编代码相同?

标签 c assembly

我正在读这本书:CS-APPe2。 C 有 unsigned 和 signed int 类型,在大多数体系结构中使用二进制补码算法来实现有符号值;但是学习了一些汇编代码后,我发现很少有指令区分unsigned和signed。所以我的问题是:

  1. 编译器有责任区分带符号的和 未签名?如果是,它是如何做到的?

  2. 谁实现二进制补码算法 - CPU 还是编译器?

添加更多信息:

再学了一些指令,其实也有一些是区分signed和unsigned的,比如setg,seta等。此外,CF 和 OF 分别适用于无符号和。但是大多数整数算术指令将无符号和有符号视为相同,例如

int s = a + b

unsigned s = a + b

生成相同的指令。

那么在执行ADD s d时,CPU应该将s&d视为无符号的还是有符号的呢?或者它是无关紧要的,因为两个结果的位模式相同,编译器的任务是将底层位模式结果转换为无符号或有符号?

P.S 我正在使用 x86 和 gcc

最佳答案

在许多情况下,有符号和无符号操作在机器级别上没有区别,只是位模式的解释问题。例如考虑以下 4 位字操作:

Binary Add  Unsigned   2's comp
----------  --------   --------
  0011          3         3
+ 1011       + 11       - 5
-------     --------   --------
  1110         14        -2  
-------     --------   --------

有符号和无符号运算的二进制模式相同。请注意,减法只是负值的加法。执行 SUB 运算时,右侧操作数是二进制补码(反转位和递增)然后相加(负责的 ALU 电路是一个加法器);不是在您理解的指令级别,而是在逻辑级别,尽管可以在没有 SUB 指令的情况下实现机器并且仍然执行减法,尽管是在两条指令而不是一条指令中。

根据类型的不同,有些操作确实需要不同的指令,一般而言,编译器有责任生成适当的代码 - 架构变化可能适用。

关于c - c编译器如何处理无符号和有符号整数?为什么无符号和有符号算术运算的汇编代码相同?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19464202/

相关文章:

python - 用Python编写的指令集模拟器失败

c - 按应用程序访问链接描述文件中定义的符号

java - System.out、stdout 和 cout 是一回事吗?

c - 如何在 C 中读取文本文件中的特定行(整数)

c - 错误的数组索引不会导致错误

linux - 字符串输出函数中的垃圾

assembly - 在汇编 8086 中打印数字

linux - Intel Assembly 中的键盘缓冲区

c - 汇编 EAX 寄存器无故重置

c - 在 C 中表示复数的方法是什么?