что не так с моей версией _bittestandset - PullRequest
0 голосов
/ 08 марта 2009

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

Ответы [ 2 ]

3 голосов
/ 08 марта 2009

Не могли бы вы дать дополнительное объяснение, что не работает? Может быть, простой пример использования или около того. Трудно догадаться, что не так с кодом ..

Одна вещь, которая пока выглядит глупо: вы выполняете код операции битового теста, но игнорируете результат. Бит, который вы тестируете (и устанавливаете), попадает в флаг переноса после кода операции.

Если вы хотите получить результат, вам нужна дополнительная инструкция, чтобы перенести флаг переноса в какой-либо другой выходной регистр. (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

Поскольку у меня нет mingw с вашей точной версией, где выполняется сборка-вывод простого тестового примера, это может дать нам некоторое представление о том, что происходит неправильно.

0 голосов
/ 01 июля 2009

НЕ используйте инструкцию BTS. Это ужасно медленно. Лучшим способом было бы реализовать это с помощью простого shift + или. И в качестве бонуса, вы можете сделать это без какой-либо сборки, в чистом, переносимом C ++.

...