Разделить число с плавающей запятой в любом из регистров st на целочисленную константу в ассемблере

Мне нужно разделить число с плавающей запятой, скажем, st0 на целое число (в этом примере 2): Итак, знайте, что я могу добиться этого просто:

mov rax, 2
fild rax
fdivp st1

но есть ли более элегантная и менее громоздкая версия (и я знаю, что следующее не работает):

fidiv 2

:S, пожалуйста, дайте мне знать, если это невозможно :) заранее спасибо


person Marco Papula    schedule 05.07.2017    source источник
comment
Какой ассемблер используете?   -  person fuz    schedule 05.07.2017
comment
Обратите внимание, что инструкции fild rax нет.   -  person fuz    schedule 05.07.2017


Ответы (1)


Ни одна из инструкций x87 не поддерживает немедленные значения. Что вам нужно сделать, так это сохранить константу, на которую вы хотите разделить, в каком-то месте памяти, а затем загрузить ее неявно, используя операнд памяти:

    fdiv DWORD PTR two      ; st0 = st0 / 2
    ...

two REAL4 2.0

Обратите внимание, что деление на константы можно значительно ускорить, умножив вместо этого обратное число:

    fmul DWORD PTR two     ; st0 = st0 * 0.5 = st0 / 2
    ...

two REAL4 0.5
person fuz    schedule 05.07.2017
comment
fscale довольно медленный - person harold; 05.07.2017
comment
Таблицы @harold Agner подтверждают это! Что вы предлагаете вместо этого? - person fuz; 05.07.2017
comment
Я не могу придумать ничего лучше, чем умножить на обратное - person harold; 05.07.2017
comment
@harold Это инструкция за один цикл, так что, вероятно, этого достаточно. - person fuz; 05.07.2017
comment
Обратите внимание, что если вы на самом деле делите на целое число, вы, вероятно, захотите использовать FIDIV. Но лучше разделить нагрузку и операцию (т. е. FIDIV+FDIV), потому что это улучшит перекрытие. См. также stackoverflow.com/questions/44574993/fptan-example-x86 / - person Cody Gray; 06.07.2017