我找到了汇编指令
cltd
通过反汇编英特尔架构上的代码。我找到的描述是,它清除了%edx寄存器,但我不明白会发生什么......谁能解释一下该命令到底做了什么?
cltd
是cdq
(引用(的别名,它将eax
符号扩展到edx:eax
。
这在实践中意味着edx
填充了最高有效位eax
(符号位(。例如,如果eax
0x7F000000
edx
则在cdq
之后将变为0x00000000
。如果eax
是0x80000000
edx
就会变得0xFFFFFFFF
.
cltd
将有符号的长整型转换为有符号的双长整型
如果您想查看所发生情况的图表,请跳转到 http://download.intel.com/products/processor/manual/325462.pdf 的第 160 页(更多详细信息在第 681 页(
对我来说,这看起来很简单:cltd 通过将 EAX 的最高有效位(符号位(扩展到 EDX 的所有位,将 EAX 中的有符号长整型转换为 EDX:EAX 中的带符号长整型
比这更简单,例如:
如果位小于 0x7F000000
(十进制小于 127,则其"正"介于 0 到 127 之间。
如果位大于 0x80000000
则十进制大于 128,则其"负"介于 -1 和 -128 之间。
因此,edx 将为 pos 获得0x00000000
,为 neg 获得0xffffffff
。
例如,作为一种黑客,当您知道 eax 是 pos 编号而不是 xor rex, edx
时,它可用于清空 edx 。
附言 在某些 ASM 编译器中,cltd
可能无法0x99
编译。最好使用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 上游:
- 中新网
- CQTO