obdjump
по умолчанию -Matt
Синтаксис AT & T (как ваш 2-й кодовый блок).См. att против intel-синтаксис .Вики-теги содержат некоторую информацию о различиях синтаксиса: https://stackoverflow.com/tags/att/info против https://stackoverflow.com/tags/intel-syntax/info
Любой синтаксис имеет те же ограничения, налагаемые тем, что может делать сама машина, и тем, что кодируется в машинном коде.,Это просто разные способы выразить это в тексте.
Используйте objdump -d -Mintel
для синтаксиса Intel.Я использую alias disas='objdump -drwC -Mintel'
в своем .bashrc
, поэтому я могу disas foo.o
и получить желаемый формат с распечатанными перемещениями (важно для понимания несвязанного .o
), без строки-пакет для длинных инструкций и с разделенными именами символов C ++.
Во встроенном asm вы можете использовать любой синтаксис, если он соответствует ожидаемому компилятором.По умолчанию используется AT & T, и это то, что я бы рекомендовал использовать для совместимости с clang.Может быть, есть способ, но clang не работает так же, как GCC с -masm=intel
.
Кроме того, AT & T в основном стандарт для встроенного asm GNU C на x86, и это означает, что вам не нужны специальныеОпции сборки для работы вашего кода.
Но вы можете использовать gcc -masm=intel
для компиляции исходных файлов, использующих синтаксис Intel в их операторах asm
.Это хорошо для вашего собственного использования, если вас не волнует лязг.
Если вы пишете код для заголовка, вы можете сделать его переносимым междуСинтаксис AT & T и Intel с использованием альтернативных диалектов, по крайней мере для GCC:
static inline
void atomic_inc(volatile int *p) {
// use __asm__ instead of asm in headers, so it works even with -std=c11 instead of gnu11
__asm__("lock {addl $1, %0 | add %0, 1}": "+m"(*p));
// TODO: flag output for return value?
// maybe doesn't need to be asm volatile; compilers know that modifying pointed-to memory is a visible side-effect unless it's a local that fully optimizes away.
// If you want this to work as a memory barrier, use a `"memory"` clobber to stop compile-time memory reordering. The lock prefix provides a runtime full barrier
}
source + asm для gcc / clang в проводнике компилятора Godbolt .
При g++ -O3
(по умолчанию или -masm=att
) мы получаем
atomic_inc(int volatile*):
lock addl $1, (%rdi) # operand-size is from my explicit addl suffix
ret
При g++ -O3 -masm=intel
мы получаем
atomic_inc(int volatile*):
lock add DWORD PTR [rdi], 1 # operand-size came from the %0 expansion
ret
лязгработает с версией AT & T, но не работает с -masm=intel
(или -mllvm --x86-asm-syntax=intel
, что подразумевается), потому что это, очевидно, относится только к коду, генерируемому LLVM, а не к тому, как внешний интерфейс заполняет шаблон asm.
Сообщение об ошибке clang:
<source>:4:13: error: unknown use of instruction mnemonic without a size suffix
__asm__("lock {addl $1, %0 | add %0, 1}": "+m"(*p));
^
<inline asm>:1:2: note: instantiated into assembly here
lock add (%rdi), 1
^
1 error generated.
Он выбрал альтернативный синтаксис Intel, но все еще заполнен в шаблоне с операндом памяти AT & T.