试图理解汇编指令:x86 上的 cltd



我找到了汇编指令

cltd

通过反汇编英特尔架构上的代码。我找到的描述是,它清除了%edx寄存器,但我不明白会发生什么......谁能解释一下该命令到底做了什么?

cltd

cdq(引用(的别名,它将eax符号扩展到edx:eax

这在实践中意味着edx填充了最高有效位eax(符号位(。例如,如果eax 0x7F000000 edx则在cdq之后将变为0x00000000。如果eax0x80000000 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

最新更新