我找到了组装说明
cltd
通过反汇编英特尔架构上的代码。我发现的描述是,它清除了 %edx 寄存器,但我不明白会发生什么......谁能解释一下该命令的确切作用?
cltd
是cdq
( reference ) 的别名,其符号扩展eax
为edx:eax
.
这在实践中意味着它被(符号位)edx
的最高有效位填充。eax
例如, if eax
is0x7F000000
edx
会变成0x00000000
after cdq
。如果eax
是0x80000000
edx
会变成0xFFFFFFFF
.
cltd
将有符号长转换为有符号双长
如果您想查看所发生情况的图表,请跳转到http://download.intel.com/products/processor/manual/325462.pdf的第 160 页(第 681 页上的更多详细信息)
比这更简单,例如:
如果该位小于0x7F000000
,即小于十进制的 127,则其“正数”介于 0 到 127 之间。
如果该位大于0x80000000
十进制的 128,则其“负数”介于 -1 和 -128 之间。
所以 edx 会得到0x00000000
pos 和0xffffffff
neg。
例如,当您知道 eax 是 pos 号而不是xor rex, edx
.
PScltd
可能无法像0x99
在某些 asm 编译器中那样编译。更好用cdq
Michael 提到的文档摘要:
Intel AT&T From To
CBW CBTW AL AX
CWDE CWTL AX EAX
CWD CWTD AX DX:AX
CDQ CLTD EAX EDX:EAX
CDQE CLTQ EAX RAX
CQO CQTO RAX RDX:RAX
现在一些注释代码片段:
/* Quad to Octo: top bit is zero: extend with zeroes. */
mov $0x7FFFFFFFFFFFFFFF, %rax
mov $0x123456789ABCDEF0, %rdx
cqto
mov %rax, %r12
mov %rdx, %r13
/* rax is unchanged. */
LKMC_ASSERT_EQ(%r12, $0x7FFFFFFFFFFFFFFF)
/* rdx is filled with zeros. */
LKMC_ASSERT_EQ(%r13, $0)
/* Quad to Octo: top bit is one: extend with ones. */
mov $0x8000000000000000, %rax
mov $0x123456789ABCDEF0, %rdx
cqto
mov %rax, %r12
mov %rdx, %r13
LKMC_ASSERT_EQ(%r12, $0x8000000000000000)
LKMC_ASSERT_EQ(%r13, $0xFFFFFFFFFFFFFFFF)
/* Intel equivalent syntax also accepte by GNU GAS. */
mov $0x7FFFFFFFFFFFFFFF, %rax
mov $0x123456789ABCDEF0, %rdx
cqo
mov %rax, %r12
mov %rdx, %r13
LKMC_ASSERT_EQ(%r12, $0x7FFFFFFFFFFFFFFF)
LKMC_ASSERT_EQ(%r13, $0)
/* Smaller size example: Double to Quad.
* Also zeroes top 32-bits of RDX like many 32 to 64 operaions. */
mov $0xFFFFFFFF7FFFFFFF, %rax
mov $0x123456789ABCDEF0, %rdx
cltd
mov %rax, %r12
mov %rdx, %r13
LKMC_ASSERT_EQ(%r12, $0xFFFFFFFF7FFFFFFF)
LKMC_ASSERT_EQ(%r13, $0)
/* Even smaller size example: Word to Doubleword.
* Unlike the 32-bit one, does not zero out the top 32-bits of RDX. */
mov $0xFFFFFFFFFFFF7FFF, %rax
mov $0x123456789ABCDEF0, %rdx
cwtd
mov %rax, %r12
mov %rdx, %r13
LKMC_ASSERT_EQ(%r12, $0xFFFFFFFFFFFF7FFF)
LKMC_ASSERT_EQ(%r13, $0x123456789ABC0000)
和
/* CLTQ: top bit is zero: extend with zeroes. */
mov $0x123456787FFFFFFF, %rax
cltq
LKMC_ASSERT_EQ(%rax, $0x000000007FFFFFFF)
/* CLTQ: top bit is one: extend with ones. */
mov $0x1234567880000000, %rax
cltq
LKMC_ASSERT_EQ(%rax, $0xFFFFFFFF80000000)
/* CWTL: zeroes top 32-bits. */
mov $0x123456789ABC8EF0, %rax
cwtl
LKMC_ASSERT_EQ(%rax, $0xFFFF8EF0)
CWTL
/* CBTW. */
mov $0x123456789ABCDE80, %rax
cbtw
LKMC_ASSERT_EQ(%rax, $0x123456789ABCFF80)
CWTL
可运行的 GitHub 上游: