News:

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

fisttp problem

Started by allynm, June 18, 2011, 04:00:59 PM

Previous topic - Next topic

allynm

Hello everyone,

I am trying to write a 16 bit proc that converts a float to ASCII.  Working from a template originally written by Richard Detmer I have found that ml doesn't like the FISTTP instruction and kicks it out with a "syntax error" message.  According to Raymond F. not all assemblers implement the FISTTP instruction and maybe this is true when running under NTVDM.EXE as I am doing.  At any rate, can someone suggest a work-around so I can avoid using FISTTP?  Below is snippet showing where the problem occurs.


fordigit:
fisub digit
fmul ten
fld st
fisttp digit ;l generates an error message.  FISTP assembles but I need the truncation, not rounding
mov bx, digit
or bx, 30h
mov byte ptr [di], bl
inc di
loop fordigit




Thanks,
Mark Allyn

qWord

hi,
here a code snipped thats truncating st(0):
fstcw WORD ptr [esp-2]
movzx eax,WORD ptr [esp-2]
or eax,0c00h
mov [esp-4],ax
fldcw [esp-4]
frndint
fldcw WORD ptr [esp-2]


BTW: FISTTP is an SSE3 instruction, so you may need to use an newer ml version. (Also you processor must support it)
FPU in a trice: SmplMath
It's that simple!

allynm

Hi  Qword,

Thanks very much.  I did some more digging and came up with what looks like the same solution as yours, but fewer lines of code.  I haven't tested the speed versus your solution and I make no claims as to whether it is faster or more elegant.  It just works (as does yours)

I declare a word variable in .data  named ctlwrd.  Then in the code I write:

fstcw  ctlwrd
or       ctlwrd, 110000000000b  ; i.e. C00h
fldcw  ctlwrd

I'm using the ml.exe that comes with MASM32.  I seem to recall that it is V. 6.9.  I've got 6.15 around and I could test your theory. 

Thanks for your help.

Mark

jj2007

Try this:

push ax
fldpi
dd 240CDB67h ; fisttp word ptr [esp]
pop ax


Works for my suite of assemblers.

raymond

Quotefstcw  ctlwrd
or       ctlwrd, 110000000000b  ; i.e. C00h
fldcw  ctlwrd

Unless you want to continue using that rounding control (i.e. truncate) until the end of your app, you would still need some more code to revert to the previous rounding control or some other one.

Assuming your app is for personal use and your processor can accept this instruction, the easiest way is not to foul around with the rounding control but hard code the instruction as described at the end of Chap. 5:
http://www.ray.masmcode.com/tutorial/fpuchap5.htm
When you assume something, you risk being wrong half the time
http://www.ray.masmcode.com

jj2007

Quote from: raymond on June 19, 2011, 02:48:10 AM
...hard code the instruction as described at the end of Chap. 5:
http://www.ray.masmcode.com/tutorial/fpuchap5.htm

Quote...the following opcodes assume that the EAX register contains the pointer.

Encoding      Description
DF 08     Store as a truncated WORD
DB 08     Store as a truncated DWORD
DD 08     Store as a truncated QWORD

Raymond,

Mark codes in 16 bit, that's why I chose fisttp word ptr [esp] above. Also, why use [eax] if you simply can pop the resulting integer from the stack?

By the way: fisttp word ptr [esp] is what NDISASM.EXE sees; but it works apparently as fisttp dword ptr [esp], see attachment with a full-fledged usage example. I adapted MichaelW's PrintDec routine to dword size in order to display the result.

push eax
fldpi
fmul OneMillion
dd 240CDB67h ; hardcoded fisttp dword ptr [esp] - ndisasm.exe sees it as word, though
call PrintDec

The attachment works with ml 6.14 and higher as well as with JWasm, but remember you need /omf with 6.15 and higher, and the 16-bit linker for this archaic stuff :wink

raymond

QuoteAlso, why use [eax] if you simply can pop the resulting integer from the stack?

I used EAX register in my suggested example because it is very versatile. You can use it as a pointer to any memory area where the stored data will be most useful in the circumstances (and that register can generally be trashed without too much concern). If the most useful memory area would be the stack, you can always do it as follows:

push eax
mov eax,esp
dw  8DBh
When you assume something, you risk being wrong half the time
http://www.ray.masmcode.com