数字的二进制补码表示
Two's complement representation of numbers
问题是关于练习题 2.18 来自 Randal Bryant 的 Computer Systems: A Programmer Perspective 其中指出:
For the lines labeled A–I (on the right) in the following listing, convert the hexadecimal values (in 32-bit two’s-complement form) shown to the right of the instruction names (sub, mov, and add) into their decimal equivalents (this is a disassembled program):
4004d0: 48 81 ec e0 02 00 00 sub [=10=]x2e0,%rsp
A
736
4004d7: 48 8b 44 24 a8 mov -0x58(%rsp),%rax
B
-88
...
...
...
如果我从问题 “显示在指令名称的右侧” 中理解正确,则表示这些值 - 0x2e0
和 -0x58
。但它们似乎不是二进制补码形式,它们只是前面有负号的无符号整数(可能我遗漏了什么)。
我哪里理解错了?以补码形式写入的 32 位十六进制值在哪里?
这是个奇怪的问题,是的。它们在机器代码的 hexdump 中是 little-endian 2 的补码,但是在反汇编中向您显示 sign/magnitude 人类可读的十六进制会让游戏失败:是的,您只需对magnitude 部分,并保留符号。
例如在SUB指令编码中:
48 81 ec e0 02 00 00 sub [=10=]x2e0,%rsp
REX.W=1 opcode modrm imm32 (little-endian)
或者在mov中:
48 8b 44 24 a8 mov -0x58(%rsp),%rax
REX.W=1 opcode ModRM SIB disp8 (signed 8-bit 2's complement)
a8
位移符号扩展为64位地址大小为0xffffffffffffffA8
;在 CPU 硬件中,寻址模式是加 RSP。
或者更容易获得人类可读的 sign/magnitude 表示,只需执行 0xa8 - 0x100 = -0x58
范围移位/解码这个具有其符号位集的 8 位 2 的补码位模式.
(或者当然取 2 的补码逆来得到大小并记住它是负的,例如 0x00 - 0xa8
换行到 8 位,或者使用 -x = ~x+1
identity 出于某种原因,许多人更喜欢从零减去一个简单的减法。)
问题是关于练习题 2.18 来自 Randal Bryant 的 Computer Systems: A Programmer Perspective 其中指出:
For the lines labeled A–I (on the right) in the following listing, convert the hexadecimal values (in 32-bit two’s-complement form) shown to the right of the instruction names (sub, mov, and add) into their decimal equivalents (this is a disassembled program):
4004d0: 48 81 ec e0 02 00 00 sub [=10=]x2e0,%rsp |
A | 736 |
4004d7: 48 8b 44 24 a8 mov -0x58(%rsp),%rax |
B | -88 |
... | ... | ... |
如果我从问题 “显示在指令名称的右侧” 中理解正确,则表示这些值 - 0x2e0
和 -0x58
。但它们似乎不是二进制补码形式,它们只是前面有负号的无符号整数(可能我遗漏了什么)。
我哪里理解错了?以补码形式写入的 32 位十六进制值在哪里?
这是个奇怪的问题,是的。它们在机器代码的 hexdump 中是 little-endian 2 的补码,但是在反汇编中向您显示 sign/magnitude 人类可读的十六进制会让游戏失败:是的,您只需对magnitude 部分,并保留符号。
例如在SUB指令编码中:
48 81 ec e0 02 00 00 sub [=10=]x2e0,%rsp
REX.W=1 opcode modrm imm32 (little-endian)
或者在mov中:
48 8b 44 24 a8 mov -0x58(%rsp),%rax
REX.W=1 opcode ModRM SIB disp8 (signed 8-bit 2's complement)
a8
位移符号扩展为64位地址大小为0xffffffffffffffA8
;在 CPU 硬件中,寻址模式是加 RSP。
或者更容易获得人类可读的 sign/magnitude 表示,只需执行 0xa8 - 0x100 = -0x58
范围移位/解码这个具有其符号位集的 8 位 2 的补码位模式.
(或者当然取 2 的补码逆来得到大小并记住它是负的,例如 0x00 - 0xa8
换行到 8 位,或者使用 -x = ~x+1
identity 出于某种原因,许多人更喜欢从零减去一个简单的减法。)