intel2gas
, очевидно, не реализует поддержку MSVC для того, чтобы оставить возвращаемое значение в EAX (или ST0) в asm, а затем опустить конец функции, не являющейся void
.MSVC воспринимает это как фактическое возвращаемое значение даже при включении функции, содержащей блок __asm
.В встроенном ассемблере GNU C значения регистров являются выходными, только если вы используете ограничения вывода или чтения / записи.
Вот почему вы получаете warning: no return statement in function returning non-void
и неработающий код.
Как указывает @MichaelPetchВы должны запросить у компилятора уже введенный номер плавающего указателя в стеке регистров FP x87, используя ограничение t
(вершина стека x87).
double raiz (double n) {
__asm__ ("fsqrt"
: "+t"(n) // read-write operand: top of x87 stack
);
return n;
}
asm volatile
не требуется:В блоке asm нет побочных эффектов, которые нужно запускать, даже если вывод не используется, а вывод является чистой функцией ввода.(Если вы не изменяете режим округления x87 или точность).
Можно позволить компилятору оптимизировать его или CSE между несколькими запусками.
Как отдельная функцияэто компилируется ( на Godbolt ) в
# gcc8.2 -O3 -ffast-math -m32 uses x87 by default, not SSE2
_Z4raizd:
fld QWORD PTR [esp+4]
# start of inline asm
fsqrt
# end of inline asm.
ret