Вопрос

Я новичок в ассемблере. Кажется, что у 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 ++.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top