cltq
знак расширяет EAX в RAX.Это краткая форма movslq %eax, %rax
, сохраняющая байты кода.Он существует из-за того, что x86-64 эволюционировал с 8086 до 386 до AMD64.
Он копирует знаковый бит EAX во все старшие биты расширенного регистра, потому что так работает дополнение 2.Мнемоника - сокращение от Convert Long to Quad.
Синтаксис AT & T (используется GNU as
/ objdump
) использует некоторые мнемоники, нежели Intel, для некоторых инструкций (см. Официальные документы )1011 *).Вы можете использовать objdump -drwC -Mintel
или gcc -masm=intel -S
, чтобы получить синтаксис Intel с использованием мнемоники, которую Intel и AMD описывают в своих руководствах по инструкциям (см. Ссылки в вики-теге x86 .факт: в качестве входных данных газ принимает либо мнемонику в любом режиме).
machine mnemonics: MOVSX equivalent
code AT&T Intel AT&T Intel
66 98 cbtw cbw movsbw %al,%ax movsx ax,al
98 cwtl cwde movswl %ax,%eax movsx eax,ax
48 98 cltq cdqe movslq %eax,%rax movsxd rax,eax
Intel insn ref ручной ввод для этих 3 insns .
cltq
/ cdqe
, очевидно, доступен только в 64-битном режиме, но два других доступны во всех режимах. movsx
и movzx
были введены только с 386, что позволяет легко / эффективно подписывать / обнулятьрасширять регистры, отличные от al
/ ax
, или подписывать / обнулять расширение на лету во время загрузки.
Думайте о cltq
/ cdqe
как о специальном случае более короткого кодирования movslq %eax,%rax
Он работает так же быстро. Но единственным преимуществом является сохранение пары байт кода, поэтому не стоит жертвовать чем-то другим, чтобы использовать его вместо movsxd
/ movzx
.
Связанная группа инструкций копирует бит знака [e / r] ax во все биты [e / r] dИкс. Расширение знака eax
в edx:eax
полезно перед idiv
или просто перед возвратом широкого целого числа в паре регистров.
AT&T / Intel mnemonic effect
66 99 cwtd cwd word->doubleword dx = signbit(ax)
99 cltd cdq doubleword->quadword edx = signbit(eax)
48 99 cqto cqo quadword->octword rdx = signbit(rax)
У них нет ни одногоэквивалентный инструкции, но вы можете сделать их в двух инструкциях: например, mov %eax, %edx
/ sar $32, %edx
.
Вспоминая мнемонику
Мнемоника Intel для расширенияв пределах rax
все оканчивается на e
, за исключением исходного 8086 cbw
.Вы можете помнить этот случай, потому что даже 8086 обрабатывали 16-битные целые числа в одном регистре, поэтому нет необходимости устанавливать dl
в знаковый бит al
.div r8
и idiv r8
читать дивиденды от ax
, а не от dl:al
.Так что cbw
sign-extends al
в ax
.
Мнемоника AT & T не имеет очевидного намека на то, чтобы помочь вам вспомнить, какой из них есть какой.Некоторые из тех, которые пишут в *dx
, заканчиваются d
(для dx?) Вместо обычного l
для long
.cqto
нарушает этот шаблон, но октавное число равно 128b и, следовательно, должно быть объединением rdx:rax
.
IMO мнемонику Intel легче запомнить, а синтаксис Intel легче читать в целом.(Сначала я выучил синтаксис AT & T, но привык к Intel, потому что чтение руководств Intel / AMD полезно!)
Обратите внимание, что для нулевого расширения, mov %edi,%edi
нулевого расширения%edi
в %rdi
, поскольку любая запись в 32-битный регистр обнуляет старшие 32 бита .(Но на практике попробуйте mov
в другой регистр (например, mov %eax, %ecx
), потому что тот же самый побеждает mov-elission в процессорах Intel . Вы часто будете видеть сгенерированный компилятором asm для функций с 32-битные аргументы без знака используют mov
для расширения нуля и, к сожалению, часто с тем же регистром, что и src и destination.
Для 8 или 16 из 32 (или неявно 64), and $0xff, %eax
работает кака также movzbl %al, %eax
. (Или лучше movzbl %al, %ecx
, так что mov-elission может сделать нулевую задержку на процессорах, где movzx
).