что не так с моей версией _bittestandset
-
05-07-2019 - |
Вопрос
Я новичок в ассемблере. Кажется, что у gcc нет функции _bittestandset в intrin.h, как у MSVC, поэтому я реализовал новую. В Linux это отлично работает, но с mingw на машине winVista это не так, код:
inline unsigned char _bittestandset(unsigned long * a, unsigned long b)
{
__asm__ ( "bts %1, %[b]"
: "=g"(*a)
: [b]"Ir"(b), "g"(*a) );
return 0;
}
Решение
Не могли бы вы дать дополнительное объяснение, что не работает? Может быть, простой пример использования или около того. Трудно догадаться, что не так с кодом ..
Одна вещь, которая пока выглядит глупо: вы выполняете код операции битового теста, но игнорируете результат. Бит, который вы тестируете (и устанавливаете), попадает в флаг переноса после кода операции. Р>
Если вы хотите получить результат, вам нужна дополнительная инструкция, чтобы перенести флаг переноса в какой-либо другой выходной регистр. (SBB EAX, EAX или что-то в этом роде). Р>
В противном случае - если вам не нужен результат - гораздо дешевле заменить инструкцию BTS тремя более простыми кодами ассемблера:
Что-то в этом роде:
; bit-index in cl
; Value in ebx
; eax used as a temporary (trashed)
mov eax, 1
shl eax, cl
or ebx, eax
Поскольку у меня нет точной версии с вашей версией, где выполняется сборка-вывод простого тестового примера, это может дать нам некоторое представление о том, что происходит не так.
Другие советы
НЕ используйте инструкцию BTS. Это ужасно медленно. Лучшим способом было бы реализовать это с помощью простого shift + или. И в качестве бонуса, вы можете сделать это без какой-либо сборки, в чистом, переносимом C ++.