News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests

Main Menu

Help with accessing the data in Tag Word register

Started by Chris., August 22, 2017, 02:08:52 AM

Previous topic - Next topic

Chris.

I HAVE ADDED FULL CODE

The issue is that I want to diagnose what is causing line: (fld $Tvalueinc[ecx]) to cause 1#IND after the 1st loop of $repeat.

I just want to utilize fnstenv/fstenv to view the TAG WORD register values to diagnose some issues, I understand its functions based on the Intel manual.






.386
.model flat, stdcall
option casemap :none 

includelib \masm32\lib\msvcrt.lib
sprintf proto C :vararg
includelib \masm32\lib\user32.lib
MessageBoxA proto :ptr,:ptr,:ptr,:DWORD
includelib \masm32\lib\kernel32.lib
ExitProcess proto :dword

.data
   _title db "Result",13,10,0
   $interm db "%0.4f","+","%0.5f",13,10,0
   Aval REAL8 1.000
   Bval REAL8 -2.000
   Cval REAL8 19.000
   _fourval REAL8 4.000
   $Tvalueinc REAL4 1.0,2.0,3.0,4.0,5.0,6.0,7.0,8.0,9.0,10.0
   $sampleval real10 4478784.0
   squareroot dq ?
   $prevCW dw ?


 
 
.code
main PROC
LOCAL szBuf[9]:byte
fstcw $prevCW
fwait
fld Bval ;  [loads first instance of b]]
fmul Bval ; [b*b = b^2]
fld Aval ;[Load a (a*c)]
fmul Cval ;(a*c)
fmul _fourval ;[4*a*c]
fsubp;[b^2-4*a*c]
ftst ;compare ST(0) with 0.0
fstsw ax ;[store camparison results in ax]
fwait;wait
sahf ;transfer flags from AH register
mov ecx, 04h
jb _negative ;jump if <0
fsqrt ;sqrt(b^2-4*a*c)
jmp Finished



_negative:
fld $sampleval


$repeat:
mov ax, $prevCW


push eax
fldcw [esp]
fld $Tvalueinc[ecx]
fstenv [esi]
mov eax,[esi+28]
fstsw ax

fdivp
FRNDINT
fldcw $prevCW
pop eax
fincstp


jne $repeat






Finished: 

   fstp squareroot
   mov eax, dword ptr squareroot
   mov edx, dword ptr squareroot[4h]
   invoke sprintf, addr szBuf, offset $interm, eax, edx
   invoke MessageBoxA, 0, addr szBuf, offset _title, 0
   invoke ExitProcess, 0



main ENDP
END main

jj2007

Your code doesn't build:Tmp_File.asm(31) : Error A2102: Symbol not defined : $Tvalueinc
Tmp_File.asm(50) : Error A2102: Symbol not defined : squareroot
Tmp_File.asm(51) : Error A2102: Symbol not defined : squareroot
Tmp_File.asm(52) : Error A2102: Symbol not defined : squareroot
Tmp_File.asm(53) : Error A2102: Symbol not defined : $interm
Tmp_File.asm(54) : Error A2102: Symbol not defined : _title
Tmp_File.asm(54) : Error A2147: Too few arguments to INVOKE: MessageBoxA


Why don't you try to build your code successfully before posting it?

raymond

That partial code makes it extremely difficult to understand what you are attempting to do. However, I added comments to some of your code and you may want to explain some of the included question marks.

Quote.386                     ;you should use .686, some instructions not being recognized by the older .386

mov ax, $prevCW
push eax
fldcw [esp]            ;can be more easily done with 'fldcw $prevCW'
fld $Tvalueinc[ecx]
fnstenv [esp]        ;overwrite 28 bytes of the stack with the 28 bytes of the environment ????
fwait
mov eax,esp         ;copy the address of the stack to EAX ????
fstsw ax               ;then overwrite the lower 16 bits of EAX with the Status Word of the fpu ?????
fdivp
FRNDINT
fst st(1)               ;overwrite the content of st(1) with the content of st(0) ?
Whenever you assume something, you risk being wrong half the time.
http://www.ray.masmcode.com

Chris.

I added rest of code
This code generates "Exception thrown at 0x0040105F in Project.exe: 0xC0000005: Access violation writing location 0x00401008.

In the disassembler i searched for 0x00401008 address and found:


00401008 55                   push        ebp

So i am unable to push the 32-bit base pointer? correct?

Once you get past the exception thrown error (By removing: fstenv [esi]
mov eax,[esi+28]
)

You will find that fstenv [esi]
mov eax,[esi+28]

causes a #1IND in ST(0), during 2nd loop attempt, which after some research led me to attempt to understand how to view the TAG WORD in the first place.

jj2007

So you decided to try what happens if you do...
fstenv [esi]
... without ever considering the option to let esi point to some piece of memory? And it doesn't work?  ::)

Btw your code is unreadable.main PROC
LOCAL szBuf[9]:byte
fstcw $prevCW
fwait
fld Bval ;  [loads first instance of b]]
fmul Bval ; [b*b = b^2]
fld Aval ;[Load a (a*c)]
fmul Cval ;(a*c)
fmul _fourval ;[4*a*c]
fsubp;[b^2-4*a*c]
ftst ;compare ST(0) with 0.0
fstsw ax ;[store camparison results in ax]
fwait;wait
sahf ;transfer flags from AH register
mov ecx, 04h
jb _negative ;jump if <0
fsqrt ;sqrt(b^2-4*a*c)
jmp Finished

raymond

QuoteSo i am unable to push the 32-bit base pointer? correct?

WRONG. The "Access violation writing location 0x00401008" message only means that your program is trying to write data in the code section because of the instruction at 0x0040105F. This is definitely not allowable. According to what you are reporting, the ESI register somehow seems to have been containing that 0x00401008 address where you instructed the fpu to store the environment.

Then, you have the fincstp instruction just before the jne $repeat instruction.

Could you explain what you were attempting to do with that fincstp instruction.

In your case, its effect would be to bring about empty fpu registers as the top register which you would then try to use with other instructions. This is definitely not allowable either. You will have to learn carefully how to use the fpu and control the content of its registers before expecting to be successful in programming it. READ THE TUTORIAL.

BTW, if you read the description of the fincstp instruction, it has absolutely no effect on the ZERO flag. Assuming you wouldn't have any exception thrown at you, your program would never have ended. And, you would always have loaded the same value from the $Tvalueinc[ecx] array by not modifying the ECX register.
Whenever you assume something, you risk being wrong half the time.
http://www.ray.masmcode.com

Chris.

It was just a leftover because I suspected that maybe the 1#IND was caused by loading data into an occupied register.
you can disregard any fincstp and fdecstp instructions, They were only for experimenting.

I have it repeating intentionally just to test things.

Very early on when I very first started messing with the FPU I found out it works similarly to my HP-32s RPN calculator that was given to me, with minor differences.

It should always divide the $samplevalue by 2, instead I get 1#IND when I want to load 2 on 2nd loop.

And now would be a good time to understand how to use the TAG WORD register.

aw27

Quote
I just want to utilize fnstenv/fstenv to view the TAG WORD register values to diagnose some issues, I understand its functions based on the Intel manual.
I would read instead the Raymond tutorial.  :idea:

jj2007

Quote from: Chris. on August 22, 2017, 11:38:01 AM
And now would be a good time to understand how to use the TAG WORD register.

And now would be a good time to study all those opcodes that you are throwing at the cpu without having a plan. To make your life as a student easier, I've posted them here. And, as aw27 wrote above, Raymond's tutorial is also an excellent source.

Unfortunately, even these manuals will not explain to you that when using fstenv [esi], the register esi must contain a so-called "address". So you may be forced to read something even more basic, such as AoA. I know, reading is hard, and you would prefer to just play around, but if you want to become a coder one day, you cannot postpone forever reading the manuals.