News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

QWORD mod Constant

Started by Artoo, June 16, 2005, 11:03:15 AM

Previous topic - Next topic

Artoo


What would the best way to calculate:

QWORD mod CONST ??


Thanks in advance!  :toothy

roticv

Use a calculator  :toothy

How big is the constant btw?

AeroASM

MyQword dq 59

mov eax,[offset MyQword]
mov edx,[offset MyQword+4]
mov ecx,5
div ecx
print ustr$(edx)

roticv

There's 2 problems with your code.

1) It wouldn't work if the const is qword. (That's why I asked about size of constant)
2) If qword/const is bigger than a dword, there would be an exception (#DE).

dsouza123

This should work with 63 bit qwords ( bit 63 == 0 ) ie positive integers,
things to test for to skip the routine :
n < d  no need  n is answer
n = d  no need  0 is answer
d = 0  no need  ? is answer
d = 1  no need  0 is answer


    .data
    n  dq 12345678901234567;
    d  dq 12345;
    m  dq 0
    holdcw dw 0

;   m := n - d*int(n / d);

; load n,d  div n,d
    finit
    fild  n
    fild  d
    fdivrp st(1),st      ; div d,n  result in st

; truncate
    ; xor     eax,eax
    fstcw   ax           ; store cw
    mov     holdcw, ax   ; make backup copy
    and     ax, ??       ; change cw round mode to truncate (round to zero)
    or      ax, ??       ;
    fldcw   ax           ; load with truncate mode
    frndint              ; truncate
    mov     ax, holdcw   ; retrieve original mode from backup copy
    fldcw   ax           ; reload original cw

; reload d   mul *d
    fild  d
    fmulp st(1),st
   
; reload n   sub  n -
    fild  n
    fsubp st(1),st
       
; store m   
    fistp m

dsouza123

If d is a power of two, ie only 1 bit set
64 bit subtract   d = d - 1
64 bit and   m = n and d

    n  dq 12345678901234567
    d  dq 65536
    m  dq 0

d = 65536
d = d - 1
m = n and d = 19335

dsouza123

Revised ( working ) qword mod using FPU.


    .586
    .model flat, stdcall
    option casemap :none

    include \masm32\include\windows.inc
    include \masm32\include\kernel32.inc
    include \masm32\include\user32.inc

    includelib \masm32\lib\kernel32.lib
    includelib \masm32\lib\user32.lib

    .data
    n       dq 12345678901234567
    d       dq 12345
    m       dq 0
    holdcw  dw 0

    .code
start:

;    should work for 63 bit numbers
;    check if d0 = 0,1 then don't use routine
   

; load d,n  div d,n
    finit
    fild  d
    fild  n
    fdivrp st(1),st      ; div d,n  result in st

; truncate
  ; xor     eax,eax
    fstcw   holdcw       ; store cw
    mov     ax, holdcw   ; make backup copy
    or      holdcw, 3072 ; change cw round mode to truncate
    fldcw   holdcw       ; load cw
    frndint              ; truncate
    mov     holdcw, ax   ; retrieve original mode from backup copy
    fldcw   holdcw       ; reload original cw

; reload d
    fild  d
    fmulp st(1),st
   
; reload n
    fild  n
    fxch
    fsubp st(1),st
       
; store m   
    fistp m

    mov eax, 1
    invoke ExitProcess,eax
end start

Artoo

Thanks for all ya help....

My CONST is only a byte in size.  The QWORD is a time64 value and the const is 60, as I want to find the number of seconds until the next minute...so the formula I would be using is "60 - (time64 mod 60)"

So would modifying AeroASM code be the simplest?

MyQword dq 59   ;time64 value returned by _time64()

mov eax,[offset MyQword]
mov edx,[offset MyQword+4]
mov ecx,60
div ecx
sub ecx,edx

print ustr$(ecx)


ECX should now contain the number of seconds until the next minute?

Ill have to try it out when i get home...

dsouza123

So _time64 holds some number of seconds ?

The modified code 

MyQword dq 59   ;time64 value
....
print ustr$(ecx)

will cause an exception for larger qword values.

Here is a revision of the FPU code

    .586
    .model flat, stdcall
    option casemap :none

    include \masm32\include\windows.inc
    include \masm32\include\kernel32.inc
    include \masm32\include\user32.inc

    includelib \masm32\lib\kernel32.lib
    includelib \masm32\lib\user32.lib

    .data
    n       dq 12345678901234567
    d       dq 60
    m       dq 0     ; 7
    holdcw  dw 0

    .code
start:
;    m := n - d*int(n / d)
    finit
    fild  n
    fild  d
    fild  n
    fdiv  st,st(1)
    fstcw   holdcw
    mov     ax, holdcw
    or      holdcw, 3072
    fldcw   holdcw
    frndint
    mov     holdcw, ax
    fldcw   holdcw
    fmulp st(1),st
    fsubp st(1),st
    fistp m

    mov eax, 0
    invoke ExitProcess,eax
end start


Working on a CPU only version, will post if it works.

dsouza123

It works !  CPU only version.


    .586
    .model flat, stdcall
    option casemap :none

    include \masm32\include\windows.inc
    include \masm32\include\kernel32.inc
    include \masm32\include\user32.inc

    includelib \masm32\lib\kernel32.lib
    includelib \masm32\lib\user32.lib

    .data
    n       dq 12345678901234567
    d       dd 60  ; 60
    m       dd 0   ;  7

    .code
start:
    mov ecx, d

    mov edx, 0
    mov eax, dword ptr n+4
    div ecx
    mov eax, dword ptr n
    div ecx
    mov m, edx

    mov eax, 0
    invoke ExitProcess,eax
end start