Как BSWAP нижний 32-битный из 64-битного регистра? - PullRequest
8 голосов
/ 07 октября 2008

Я искал ответ о том, как использовать BSWAP для нижнего 32-битного субрегистра 64-битного регистра. Например, 0x0123456789abcdef находится внутри регистра RAX, и я хочу изменить его на 0x01234567efcdab89 с помощью одной инструкции (из-за производительности).

Итак, я попробовал следующую встроенную функцию:

#define BSWAP(T) {  \
    __asm__ __volatile__ (  \
            "bswap %k0" \
            : "=q" (T)  \
            : "q" (T)); \
}

И результат был 0x00000000efcdab89. Я не понимаю, почему компилятор действует так. Кто-нибудь знает эффективное решение?

Ответы [ 2 ]

5 голосов
/ 07 октября 2008

Ах да, теперь я понимаю проблему:

процессоры x86-64 неявно расширяют ноль 32-разрядные регистры до 64-разрядных при выполнении 32-разрядных операций (на% eax,% ebx и т. Д.). Это необходимо для обеспечения совместимости с устаревшим кодом, который, как я понимаю, ожидает 32-битную семантику для этих регистров.

Так что я боюсь, что невозможно сделать ror только на младших 32 битах 64-битного регистра. Вам придется использовать серию из нескольких инструкций ...

0 голосов
/ 07 октября 2008

Проверьте вывод сборки, сгенерированный gcc! Используйте флаг gcc -s, чтобы скомпилировать код и сгенерировать вывод asm.

IIRC, x86-64 по умолчанию использует 32-разрядные целые числа, если явно не указано иное, так что это может быть (частью) проблемы.

...