Как использовать инструкции IA32 «fabs» в VS С++?
-
21-12-2019 - |
Вопрос
Это моя первая попытка использования ассемблера, и я просто пытаюсь использовать инструкцию по архитектуре 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
возьмет абсолютное значение операнда в верхней части стека с плавающей запятой и вернет результат обратно в то же место.