c - 我应该如何推断 x86-64 机器上 addb 指令的 C 数据类型?
问题描述
我有以下 C 代码,其中 v 和 b 都是有符号数据类型或指向有符号数据类型的指针。我们也知道 sizeof(b) = 2。
*v+=b
x86-64 上的汇编代码是...
addb %sil, (%rcx)
问题是 v 和 b 的 C 数据类型是什么?
我知道%sil对应b,%rcx对应v。但是,解决方案说“因为b的低位字节被添加到%rcx指向的字节,v必须是char *类型。”
我不明白为什么 v 必须是 char*。为什么不能短*?
注意:这可能是印刷错误,因为在本书的勘误表上已经发布了关于这个问题的另一个印刷错误。
解决方案
我不明白为什么 v 必须是 char*。为什么不能短*?
不可能,short*
因为它addb
是字节操作数大小,并且%sil
是一个 8 位寄存器。 short
是用于 x86-64 的 C ABI 中的 16 位类型。(ISO C 要求short
至少为 16 位。)
的操作数大小add
决定了内存中有多少字节被修改,即对象表示的大小*v
。
如果*v
是short
,即使由于某种原因我们知道b
的值很小,从低字节丢弃进位而不是让它传播到高字节也是错误的。
sizeof(b) = 2
是一个把戏/红鲱鱼:
在 C 规则中,比int
运算符 like+=
的操作数更窄的类型被提升为int
,然后将int
相加结果转换回目标类型。
所以*v += b
不关心b
是宽还是窄于*v
。 这就是为什么这个问题必须告诉你sizeof(b)
;因为您无法从指令中推断出这一点,addb
并且它不必与*v
.
在 x86-64 System V 和 Windows x64 中,唯一的 16 位整数类型是short
and unsigned short
,所以sizeof(b) == 2
告诉我们b
是short
or unsigned short
。
(那些 ABI 也有 CHAR_BIT = 8 即 1-byte char
,这对于具有字节可寻址内存的机器来说是正常的。)
固定宽度类型,例如uint8_t
and是andint16_t
的 typedef ,等等。我没有为此计算他们。unsigned char
short
这个问题还让我们排除了无符号类型,我们不能从 asm.xml 中排除。无符号加法和 2 的补码加法是相同的二进制运算。
推荐阅读
- php - 计算平均每月消耗量
- java - Java在对象中存储sql请求
- javascript - 带有 JSON 数据的 Javascript c3.js 或 billboard.js 如何获取其他图例标签
- javascript - 如何使用 TypeScript、Ant Design 和 Rollup 构建组件库
- javascript - 发出 http 请求
- python - 如何使用 GeoPandas 执行空间查询?
- swift - AVAudioPlayer 没有播放任何东西
- mongodb-atlas - MongoDB Stitch 的最大并行触发器执行限制
- c# - 函数,删除所有代码注释
- reactjs - 与 express 后端反应