News:

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

Convert SDWORD to real8 in asm file

Started by Gaurav, March 04, 2010, 04:52:27 PM

Previous topic - Next topic

GregL

Quote from: GuaravBtw clive, I'm using q-editor and the command prompt cant assemble st(0)/st(1) code... what is it?

Try using upper case ST(0), ST(1) etc., if I remember correctly, it has to do with the placement of OPTION CASEMAP:NONE.

raymond

I believe that using upper or lower case letters for mnemonics is immaterial for the MASM assembler, regardless of the casemap option. Please someone correct me if I'm wrong.

MOV eax,Ecx assembles just fine.
When you assume something, you risk being wrong half the time
http://www.ray.masmcode.com

raymond

QuoteWhat datatype is a string?

Bytes. Ex.:

inputbuffer   db  32 DUP(?)  ;or whatever size you may need
When you assume something, you risk being wrong half the time
http://www.ray.masmcode.com

GregL

Raymond,

I was talking specifically about FPU registers ST(0), ST(1) etc.

I know mmx and xmm registers can have problems with case. If you put option casemap:none before .mmx or .xmm you will have to use all uppercase for mmx and xmm registers.

I could swear I saw that same problem with ST(0) etc.  Maybe it was with PowerBASIC Inline Assembler or something.  :bg


clive

Quote from: Greg Lyon on March 06, 2010, 03:31:44 AM
Raymond,

I was talking specifically about FPU registers ST(0), ST(1) etc.

I know mmx and xmm registers can have problems with case. If you put option casemap:none before .mmx or .xmm you will have to use all uppercase for mmx and xmm registers.

I could swear I saw that same problem with ST(0) etc.  Maybe it was with PowerBASIC Inline Assembler or something.  :bg

I've always found MASM to be pretty tolerant by default, perhaps it got a bit weird when using MACROs to fake KNI/SSE back in the day but here's a quick mashup using ML -c -Fl test.asm

-Clive

Microsoft (R) Macro Assembler Version 6.15.8803     03/05/10 21:44:57
test.asm      Page 1 - 1


.686
.XMM
.MODEL FLAT

00000000 .DATA

00000000 .CODE

00000000 start:

00000000  0F F6 DA psadbw  mm3,mm2
00000003  0F F6 37 psadbw  mm6,[edi]
00000006  0F F6 DA pSadBw  Mm3,mM2
00000009  0F F6 37 PsadbW  MM6,[eDi]

0000000C  0F C6 F4 03 shufps  xmm6,xmm4,3
00000010  0F C6 13 02 shufps  xmm2,[ebx],2
00000014  0F C6 F4 03 ShufPS  xMM6,xMm4,3
00000018  0F C6 13 02 sHUFps  Xmm2,[EbX],2

END start
It could be a random act of randomness. Those happen a lot as well.

GregL

Clive,

Did your code contain OPTION CASEMAP:NONE?  The masm32 includes do use it, and it does effect case sensitivity.

I don't want to get into a pissing match about this. It was just a suggestion for Gaurav based on what I remembered happening to me in the past.

clive

QuoteDid your code contain OPTION CASEMAP:NONE?

No, pretty much plain and vanilla like the listing, not including anything either.

QuoteI don't want to get into a pissing match about this.

No problem. I've run into case problems on other assemblers, but did'nt recall running into any with MASM, which is usually pretty tolerant of case and syntax. I usually use the inline assembler, and lower case, just wanted to confirm MASM wouldn't totally choke on my code.

-Clive
It could be a random act of randomness. Those happen a lot as well.

GregL

Clive,

I just tried a few tests, OPTION CASEMAP:NONE does not seem to effect the case sensitivity of the FPU registers but it does effect the mmx and xmm registers as I described in my prior post. I guess I was thinking of that.  :red



Gaurav


.386                            ; create 32 bit code
.model flat, stdcall            ; 32 bit memory model
option casemap :none            ; case sensitive

include \masm32\include\masm32rt.inc

.data
n1 REAL8 ?                      ; the first value
n2 REAL8 ?                      ; the second value
n2prnt REAL8 ?                  ; the printable value of n2
power REAL8 ?                   ; the result of n1^abs(n2)
n2o SDWORD 0                    ; the loop counter
mine SDWORD 0                   ; getting inputs

.code
start:

    finit                       ; initialize fpu

    mov mine, sval(input("Enter 1st number: "))
    fild mine                   ; loading in the number as an integer(i want float)
    fst n1                      ; storing the number in n1
   
    mov mine, sval(input("Enter 2nd number: "))
    fild mine                   ; loading in the number as an integer(i want float)
    fabs                        ; absolute value of exponent
    fst n2                      ; storing the number in n2

    fld n2                      ; load the float n2
    fst n2prnt                  ; store as a printable var
    fist n2o                    ; store n2 as a loop counter also

wileloop:                       ; while loop
    cmp n2o, 0                  ; compare loop counter and 0
    jg powerade                 ; jump if less than, goes to label powerade
    jmp done                    ; jump to label done otherwise

powerade:                       ; do the power of the values
    fmul n1                     ; multiply n1 to it
    fst n2                      ; store register value back in n2
    dec n2o                     ; decrement the loop counter
    jmp wileloop                ; go back to the while loop

done:
    fst power                   ; store the result in power
    invoke crt_printf,chr$("The value of n1 is: %f%c"),n1,10
    invoke crt_printf,chr$("The value of n2 is: %f%c"),n2prnt,10
    invoke crt_printf,chr$("The value of power is: %f%c"),power,10

inkey
exit
end start


This is what I've got so far.. As you can see im not getting the float values through input and i can't loop an exponent of like 4.5, it only does 4. Any suggestions?

qWord

x^y can be calculated through logarithm - take a look in  (or use) Raymond's fpulib: FpuXexpY.asm
FPU in a trice: SmplMath
It's that simple!

Gaurav


.386                            ; create 32 bit code
.model flat, stdcall            ; 32 bit memory model
option casemap :none            ; case sensitive

include \masm32\include\masm32rt.inc
include \masm32\fpulib\Fpu.inc

.data
n1 REAL8 ?                      ; the first value
n2 REAL8 ?                      ; the second value
n2prnt REAL8 ?                  ; the printable value of n2
power DWORD ?                   ; the result of n1^abs(n2)
n2o SDWORD 0                    ; the loop counter
mine SDWORD 0                   ; getting inputs

.code
start:

    finit                       ; initialize fpu

    mov mine, sval(input("Enter 1st number: "))
    fild mine                   ; loading in the number as an integer(i want float)
    fst n1                      ; storing the number in n1
   
    mov mine, sval(input("Enter 2nd number: "))
    fild mine                   ; loading in the number as an integer(i want float)
    fabs                        ; absolute value of exponent
    fst n2                      ; storing the number in n2

    fld n2                      ; load the float n2
    fst n2prnt                  ; store as a printable var
    fist n2o                    ; store n2 as a loop counter also

invoke FpuXexpY, n1, n2, power, SRC1_REAL8 or SRC2_REAL8

done:
    invoke crt_printf,chr$("The value of n1 is: %f%c"),n1,10
    invoke crt_printf,chr$("The value of n2 is: %f%c"),n2prnt,10
    invoke crt_printf,chr$("The value of power is: %f%c"),power,10

inkey
exit
end start


OK, i have access to the fpu commands but how to fix this error?


(40) : error A2114: INVOKE argument type mismatch : argument : 2
(40) : error A2114: INVOKE argument type mismatch : argument : 1

clive

Quote
x^y can be calculated through logarithm

I think this has been expressed earlier, and demonstrated using x87 intrinsics, the OP is persisting with his own method.

I fail to understand the "fst n2" in the loop. You need to be using fstp's to stop the x87 getting cluttered up with junk. The integer method I previously posted is far more efficient.

You can't do a fractional exponent using the looping method here, please refer to some docs/books on the 80x87.

I'd suggest using a CRT sscanf() method for inputting the floating point value. Or using atof(). For starters you could hard code values.

The point of the assignment/homework problem is to understand the x87, not calling existing library code.

-Clive
It could be a random act of randomness. Those happen a lot as well.

raymond

Gaurav,
If you are going to use the Fpulib functions (or functions from any other library), you MUST read and understand the provided help file. For example, the FpuXexpY function specifies the following:

SRC1_REAL8   Src1 is a pointer to a 64-bit REAL number (you tried to pass the value of a REAL8 instead of its address)
SRC2_REAL8   Src2 is a pointer to a 64-bit REAL number (same as above)
DEST_MEM     lpDest is a pointer to a TBYTE
                   (this is the default and does not need to be indicated)
Since you don't specify any specific destination, the function expects that the value provided is the address of a REAL10. And, because you provided the current value of the dword variable "power" as that parameter, it was considered as a correct argument type (addresses are dwords). However, the current value of "power" was probably 0 and your program would thus have crashed (trying to write at address 0) if your first two arguments had been correct.

As a side note, that function generally expects REAL arguments as sources and thus returns a REAL result. Returning an integer is not directly possible. The help file will thus need to be altered to avoid any potential misunderstanding because of the use of the DWORD/QWORD terminology instead of REAL4/REAL8 for destinations.
When you assume something, you risk being wrong half the time
http://www.ray.masmcode.com

Gaurav

Well, I have modified the code. The problem seems to be that I cannot invoke the FpuXexpY proc at all.. everything else runs


.386                            ; create 32 bit code
;.model flat, stdcall           ; 32 bit memory model
option casemap :none            ; case sensitive

include \masm32\include\masm32rt.inc
include \masm32\fpulib\Fpu.inc

.data
n1 REAL8 ?                      ; the first value
n2 SDWORD ?                     ; the second value
power REAL10 ?                  ; the result of n1^abs(n2)

.code
start:

    finit                       ; initialize fpu

    ; getting inputs
    invoke StrToFloat, input("Enter number: "), OFFSET n1
    invoke StrToFloat, input("Enter exponent: "), OFFSET n2

    fld n1                      ; load the flat n1
    fabs                        ; make it positive
    fstp n1                     ; store it back in n1
    fld n2                      ; load the float n2
    fabs                        ; make it positive
    fstp n2                     ; store it back in n2

    fld n1                      ; loads n1 to stack
   
    invoke FpuXexpY, 0, n2, ADDR power, SRC1_FPU or SRC2_DIMM
    fstp power                  ; get the result from invoking...

done:
    print chr$("The value of n1 is: ")
    print real8$(n1)
    print chr$(10, "The value of new n2 is: ")
    print str$(n2)
    print chr$(10, "The value of power is: ")
    print real10$(power)
    print chr$(10)

inkey
exit
end start


Any suggestions?

MichaelW

You left out:

includelib \masm32\fpulib\Fpu.lib

So the essential library is not being included in the linking process, and the linker fails when it cannot resolve the reference to FpuXexpY. The linker should have returned:

error LNK2001: unresolved external symbol _FpuXexpY@16
fatal error LNK1120: 1 unresolved externals


eschew obfuscation