Как использовать инструкции IA32 «fabs» в VS С++?

Это моя первая попытка использовать сборку, и я просто пытаюсь использовать инструкцию архитектуры Intel FABS. (Ссылка на данный документ на стр. 399).

Это просто должно очистить бит знака.

То немногое, что я знаю об ассемблере, касается источников и мест назначения, но я не вижу никаких ссылок на обозначения для этой инструкции.

Ниже приведена одна из моих попыток его использования (с использованием Visual Studio 2012, C++):

double myabs(double x){
  __asm(fabs(x));
return x;
}

Эта конкретная попытка дает ошибку C2400: синтаксическая ошибка встроенного ассемблера в «коде операции»; нашел '('


Обратите внимание, что я хочу использовать инструкцию по сборке и меня не интересуют другие / «лучшие» доступные варианты.


person Automate This    schedule 17.11.2013    source источник
comment
Нет необходимости в встроенной сборке. Компилятор, скорее всего, сам встроит вызов функции fabs().   -  person Seva Alekseyev    schedule 18.11.2013


Ответы (2)


Несколько указателей: во-первых, вы используете встроенную сборку в стиле gcc, в стиле MS вы можете использовать -

__asm{ ... }

Во-вторых, инструкции не являются функциями, поэтому скобки там тоже неправильные.

Последнее, но самое важное — fabs не принимает аргумент, он просто работает на вершине стека FP. Сначала вам нужно явно загрузить свою переменную. Попробуй это:

__asm {
    fld x
    fabs
    fstp x
}

В любом случае, использование старых инструкций x87, вероятно, не очень хорошо, это, вероятно, довольно неэффективно - вам следует подумать о переходе на решение SSE, см. - Как абсолютировать 2 double или 4 float с помощью набора инструкций SSE? (до SSE4)

person Leeor    schedule 17.11.2013

В VC++ вы не заключаете язык ассемблера в круглые скобки. Правильный синтаксис будет больше похож на:

__asm fabs

or:

__asm { 
    fabs
    // possibly more instructions here
}

В вашем конкретном случае вы, вероятно, захотите что-то вроде:

__asm { 
    fload x // load x onto F.P. stack
    fabs    // take absolute value
    fstp x  // store back to x and pop from F.P. stack.
}

Что касается источника и получателя, с плавающей запятой на x86 используется стек. Если не указано иное, большинство инструкций (кроме загрузки/сохранения) берут операнды с вершины стека и помещают результаты также на вершину стека. Например, если операнд не указан, fabs возьмет абсолютное значение операнда наверху стека с плавающей запятой и поместит результат обратно на то же место.

person Jerry Coffin    schedule 17.11.2013