Версия для печати
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум на Исходниках.RU > Assembler > сопроцессор


Автор: cupoma58 28.08.18, 08:56
;Имеем 2 дробных числа с фиксированной "запятой"
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    ;dig1 dd 0,0
    ;dig2 dd 0,0
    ;res  qd 0,0,0,0    - итог арифметической операции
    ;buf  db 10 dup (0) - набранное на дисплее число

В соответствии с источником, арифметическую операцию (например - сложения) можно провести с помощью
команд сопроцессора:
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    ...
    ;копируем каждое число с дисплея в переменную:
    push eax
    movzx eax,buf
    mov  dig,eax
    pop  eax
    ...
    ;складываем числа:
    finit
    fld  dig1
    fld  dig2
    fadd
    fstp res
    ...
    push  offset buf
    push  [hedt]
    call  SetWindowTextA@8                            
    ret
    ...

Подскажите, как можно передать число из "res" в "buf", для вывода на дисплей?
:scratch:

Автор: Qraizer 28.08.18, 10:40
Для значений с фиксированной запятой FPU не нужен.

Автор: cppasm 29.08.18, 06:06
Цитата cupoma58 @
В соответствии с источником, арифметическую операцию (например - сложения) можно провести с помощью
команд сопроцессора

С каким источником?
Фиксированную точку для того и придумали, что над числами с фиксированной точкой работают целочисленные команды.
Как Qraizer уже ответил - FPU не нужен. FLD загрузит в FPU не то что ты ожидаешь.

Автор: Jin X 29.08.18, 08:03
Обычные целые числа – это числа без запятых (даже фиксированных). Для них используются обычные mov, add, sub и пр.
Если говорить о фиксированных, то тут есть варианты. В зависимости от операции и от того, как эта точка представлена.
К примеру.
4 байта, 2 старших байта - целая часть, 2 младших - дробная.
Складываем просто:
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    mov eax,X
    add eax,Y  ; результат в eax
Вычитаем так же.
А вот с умножением будет уже чуть позамороченнее:
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    mov eax,X
    imul Y  ; или mul Y для беззнакового умножения, результат в edx:eax
    shrd eax,edx,16  ; 2 младших байта eax нам не нужны, а 2 старших байта edx будут утеряны, если результат превысит допустимые границы

Для упрощения можно использовать FPU, но тогда нужно будет умножать и делить числа и результат на 65536, например.
Умножение:
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    push X
    push Y
    push dword ptr 65536
    fild dword ptr [esp+8]  ; X
    fdiv dword ptr [esp]    ; /65536
    fild dword ptr [esp+4]  ; Y
    fdiv dword ptr [esp]    ; /65536
    fmulp
    fmul dword ptr [esp]    ; *65536
    fistp Result
    add esp,12
Ну или так:
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    push X
    push Y
    push dword ptr 65536
    fild dword ptr [esp+8]  ; X
    fmul dword ptr [esp+4]  ; Y
    fdiv dword ptr [esp]    ; /65536
    fistp Result
    add esp,12

Автор: cupoma58 12.09.18, 07:26
Цитата Jin X @
Обычные целые числа – это числа без запятых (даже фиксированных). Для них используются обычные mov, add, sub и пр.
Если говорить о фиксированных, то тут есть варианты. В зависимости от операции и от того, как эта точка представлена.
К примеру.
4 байта, 2 старших байта - целая часть, 2 младших - дробная.
Складываем просто:
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    mov eax,X
    add eax,Y  ; результат в eax
Вычитаем так же.
А вот с умножением будет уже чуть позамороченнее:
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    mov eax,X
    imul Y  ; или mul Y для беззнакового умножения, результат в edx:eax
    shrd eax,edx,16  ; 2 младших байта eax нам не нужны, а 2 старших байта edx будут утеряны, если результат превысит допустимые границы

Для упрощения можно использовать FPU, но тогда нужно будет умножать и делить числа и результат на 65536, например.
Умножение:
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    push X
    push Y
    push dword ptr 65536
    fild dword ptr [esp+8]  ; X
    fdiv dword ptr [esp]    ; /65536
    fild dword ptr [esp+4]  ; Y
    fdiv dword ptr [esp]    ; /65536
    fmulp
    fmul dword ptr [esp]    ; *65536
    fistp Result
    add esp,12
Ну или так:
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    push X
    push Y
    push dword ptr 65536
    fild dword ptr [esp+8]  ; X
    fmul dword ptr [esp+4]  ; Y
    fdiv dword ptr [esp]    ; /65536
    fistp Result
    add esp,12

Тема закрыта, благодарю.
:yes:

Powered by Invision Power Board (https://www.invisionboard.com)
© Invision Power Services (https://www.invisionpower.com)