Это моя первая попытка использования сборки, и я просто пытаюсь использовать инструкцию по архитектуре Intel FABS
, (Реферирование этот документ на странице 399).
Это просто должно очистить бит знака.
Мало что я знаю о сборке, касается источников и мест назначения, но я не вижу ссылок на обозначения для этой инструкции.
Ниже приведена одна из моих попыток его использования (с использованием Visual studio 2012, C ++):
double myabs(double x){
__asm(fabs(x));
return x;
}
Эта конкретная попытка выдает ошибку C2400: ошибка синтаксиса встроенного ассемблера в ‘код операции’; найденный ‘(‘
Обратите внимание, что я хочу использовать инструкцию по сборке и мне не интересны другие / «лучшие» варианты, которые доступны.
Несколько указателей: во-первых — вы используете встроенную сборку в стиле gcc, в стиле MS, которую вы можете использовать —
__asm{ ... }
Второе — инструкции не являются функциями, поэтому круглые скобки там тоже неверны.
Последнее, но самое важное — fabs
не принимает аргумент, он просто работает на вершине стека FP. Вы должны явно загрузить свою переменную туда сначала. Попробуй это:
__asm {
fld x
fabs
fstp x
}
В любом случае, использование старых инструкций x87, вероятно, не очень хорошая вещь, возможно, довольно неэффективно — вам следует подумать о переходе на решение SSE, см. Как получить 2 двойных или 4 числа с плавающей запятой, используя набор инструкций SSE? (До SSE4)
С VC ++ вы не заключаете ассемблер в круглые скобки. Правильный синтаксис был бы больше похож на:
__asm fabs
или же:
__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
возьмет абсолютное значение операнда в верхней части стека с плавающей запятой и поместит результат обратно в то же место.