Hello,

I'm trying to do a program that compute the GCD (greatest common divisor).

It's very simple to do it with integer (ALU), but I can't do it with the math coprocessor (FPU).

Reading the Intel Manual I've seen the FPREM1 instruction, but when trying to use it it doesn't work. In fact it seems this instruction is waiting for a division just before...

The only thing I'm trying to achieve is something like a modulo operation with the FPU.

Does someone has a clue ?

Thank you very much !

Regards, Neitsa.

I'm trying to do a program that compute the GCD (greatest common divisor).

It's very simple to do it with integer (ALU), but I can't do it with the math coprocessor (FPU).

Reading the Intel Manual I've seen the FPREM1 instruction, but when trying to use it it doesn't work. In fact it seems this instruction is waiting for a division just before...

The only thing I'm trying to achieve is something like a modulo operation with the FPU.

Does someone has a clue ?

Thank you very much !

Regards, Neitsa.

Might be of some help:

http://www.azillionmonkeys.com/qed/asmexample.html

IMHO, if you are using divide then it is going to be too slow.

http://www.azillionmonkeys.com/qed/asmexample.html

IMHO, if you are using divide then it is going to be too slow.

GCD of what?! real numbers?

You need first explain what whoul you name GCD for real numbers in math terms then ask for realization.

Or you are talking of long integers? Like 64 bit and bigger?

You need first explain what whoul you name GCD for real numbers in math terms then ask for realization.

Or you are talking of long integers? Like 64 bit and bigger?

Hi ,

Bitrake : Thanks a lot for your link !

The Svin:

I'm trying to use math coprocessor to overcome the limitation of ALU register's (0xFFFFFFFF). I'm not talking about using the decimal part of real number, just using the bigger capacacity offered by FPU numbers.

To be sure that those numbers doesn't have decimal part I'm doing this:

int1 and int2 are declared with TBYTE due to FpuAtoFL.

Thanks. Neitsa.

Bitrake : Thanks a lot for your link !

The Svin:

I'm trying to use math coprocessor to overcome the limitation of ALU register's (0xFFFFFFFF). I'm not talking about using the decimal part of real number, just using the bigger capacacity offered by FPU numbers.

To be sure that those numbers doesn't have decimal part I'm doing this:

```
```

invoke FpuAtoFL,int1, addr FLOAT1,DEST_MEM ;convert string to REAL

invoke FpuAtoFL,int2, addr FLOAT2,DEST_MEM

FINIT

FLD FLOAT1 ;push on FPU stack

FRNDINT ; round it

FLD FLOAT2

FRNDINT

int1 and int2 are declared with TBYTE due to FpuAtoFL.

Thanks. Neitsa.

The FpuAtoFL function is designed to convert an ASCII text representation of the number you want to convert to a float. The first parameter must be the address of the null-terminated ASCII string. You can find all those details in the extensive Help file describing each function and provided with the FPULIB.

The FPREM instruction is of no use for what you are trying to achieve. Following is the general process you should follow:

Raymond

The FPREM instruction is of no use for what you are trying to achieve. Following is the general process you should follow:

```
```

fild qword ;Load the 64-bit integer to the FPU

fidiv dword ;Divide it by whatever integer you have to

fld st ;Copy the result to the FPU

frndint ;Round it to an integer

fsub ;Subtract it from the original result

fxam ;Examine the modulo

fstsw ax ;Transfer result to AX

fwait

sahf ; and to the flag register

jz zero_modulo

Raymond

I'm trying to use math coprocessor to overcome the limitation of ALU register's (0xFFFFFFFF).

You realize that you can use 64 bit operations very easily on x86 ALU? add/adc, sub/sbb, shrd/shld?

I would say those are a much better alternative than setting x87 to extended precision (everything else would be way less accurate), and trying to calc on that while making sure you lose no precision, and work without shifts.

This might work?

Note: signed 64-bit numbers used EAX:EDX and EBX:ECX.

EDX and ECX are the most significant DWORDs.

```
NEG64 MACRO
```

not edx

neg eax

sbb edx, -1

ENDM

SUB64 MACRO

sub eax, ebx

sbb edx, ecx

ENDM

ADD64 MACRO

add eax, ebx

adc edx, ecx

ENDM

GCD64:

NEG64

je _1a

_0: NEG64

xchg eax, ebx

xchg edx, ecx

_1: SUB64

jg _1

jne _0

_1a: test eax, eax

jne _0

_2: ADD64

jne _3

test eax, eax

jne _3

inc eax

_3: retn

Untested, but surely almost there...
Note: signed 64-bit numbers used EAX:EDX and EBX:ECX.

EDX and ECX are the most significant DWORDs.

edx::eax would be a nice way to mention then. That's MASM syntax, and it's customary to put the most significant part up first anyway.

EAX:EDX is the memory representation. The usage is purely based on the preferences of the individual and as long as it is stated to eliminate ambiguity I'm fine with either notation.

Hrm, usage is purely based on the preferences of the individual? I thought EDX:EAX was the standard notation?

If I state the usage what difference does it make? I create notation to solve a problem as it suits me - as long as the notation is documented there is no problem. I'm sorry if this causes others difficulty, but it is something I've gotten used to as I explore different areas each with their own notation.

Hello,

Just to thank you all for your answers and replies !

I think I have all in my hands to implement in 64 bits or with FPU.

Thanks again.

Regards, Neitsa.

Just to thank you all for your answers and replies !

I think I have all in my hands to implement in 64 bits or with FPU.

Thanks again.

Regards, Neitsa.