Hi Biterider,
I have my doubts about the correctness of the output of ObjAsm's DbgFPU macro. For example:
I expected to see:
- a different Level than 0.
- the contents of the stack.
- exception information.
However, the level is 0, and there is no stack or exception information.
Is the macro working properly?
Friendly regards,
mdevries.
I have my doubts about the correctness of the output of ObjAsm's DbgFPU macro. For example:
finit
fld1
fldz
fdiv st(0), st(1)
DbgFPU
fdiv st(1), st(0)
DbgFPU
I expected to see:
- a different Level than 0.
- the contents of the stack.
- exception information.
However, the level is 0, and there is no stack or exception information.
Is the macro working properly?
Friendly regards,
mdevries.
Hi mdevries
Thanks for the bug report. You are right, in one of the last changes in the debug system when I introduced the FPU state saving, I forgot to set the DBG_SAVE_FPU_CONTEXT switch for this macro.
A quick fix looks like:
but I will try to check the code again since it is outputting "FAIL" in some cases without apparent reason.
Regards,
Biterider
Thanks for the bug report. You are right, in one of the last changes in the debug system when I introduced the FPU state saving, I forgot to set the DBG_SAVE_FPU_CONTEXT switch for this macro.
A quick fix looks like:
DbgFPU macro InfoText, Dest
if DEBUGGING
??LastFpuSwitch = DBG_SAVE_FPU_CONTEXT
DBG_SAVE_FPU_CONTEXT = FALSE
DbgSaveContext
invoke EnterCriticalSection, addr DbgCritSect
ifb <Dest>
??DbgDstWnd textequ <offset szDbgSrc>
else
??DbgDstWnd textequ <Dest>
endif
@invoke DbgOutText, "FPU DUMP", $RGB(0,0,0), DBG_EFFECT_NORMAL, %??DbgDstWnd
DbgShowTxtInfo InfoText, %??DbgDstWnd
DbgShowSrcInfo %??DbgDstWnd
@invoke DbgOutFpu, %??DbgDstWnd
invoke LeaveCriticalSection, addr DbgCritSect
DbgLoadContext
DBG_SAVE_FPU_CONTEXT = ??LastFpuSwitch
endif
endm
but I will try to check the code again since it is outputting "FAIL" in some cases without apparent reason.
Regards,
Biterider
Hi
OK, I found the problem. The issue is that when I left the FPU in an exception state like when I perform a division by zero, St0ToStr will fail since it uses the FPU to represent the floating point number. This is the case when "Failed" was written in the FPU stack output.
This behavior was not considered when the macro/proc was written.
I will write to correct it into my todo list ;)
Regards,
Biterider
OK, I found the problem. The issue is that when I left the FPU in an exception state like when I perform a division by zero, St0ToStr will fail since it uses the FPU to represent the floating point number. This is the case when "Failed" was written in the FPU stack output.
This behavior was not considered when the macro/proc was written.
I will write to correct it into my todo list ;)
Regards,
Biterider
Hi Biterider,
I will do the partial quickfix in the meantime.
Thanks, for your useful and ever increasing product.
Friendly regards,
mdevries.
I will do the partial quickfix in the meantime.
Thanks, for your useful and ever increasing product.
Friendly regards,
mdevries.
Hi mdevries
I think I have found a definitive fix for that issue. Please, can you test it? It requires to recompile the ObjMem library.
Regards,
Biterider
I think I have found a definitive fix for that issue. Please, can you test it? It requires to recompile the ObjMem library.
Regards,
Biterider
Hi Biterider,
As far as I can see the exceptions flags are shown correctly now.
There is a small problem in showing the contents of the stack:
When there is only one stack register left, the level = 7.
No problem at that point: st(0) thru st(6) are shown correctly.
But after loading the last stack register, the level resets to 0.
And as a consequence, the contents of NO register is shown.
The level should be 8 instead, and ALL of the registers should be shown.
The conditinal line needs some reconsideration too.
It continuously says:
I think you didn't intend this behavior.
Friendly regards,
mdevries.
As far as I can see the exceptions flags are shown correctly now.
There is a small problem in showing the contents of the stack:
When there is only one stack register left, the level = 7.
No problem at that point: st(0) thru st(6) are shown correctly.
But after loading the last stack register, the level resets to 0.
And as a consequence, the contents of NO register is shown.
The level should be 8 instead, and ALL of the registers should be shown.
The conditinal line needs some reconsideration too.
It continuously says:
Conditional: St > Source
I think you didn't intend this behavior.
Friendly regards,
mdevries.
Hi
Unfortunately I can not reproduce what you describe. I use the following code to test the macro
and get the following output
Perhaps if you can post your code I can try to find out the problem.
Best regards,
Biterider
Unfortunately I can not reproduce what you describe. I use the following code to test the macro
%include @Environ(OA32_PATH)\\Code\\Macros\\Model.inc
SysSetup OOP_WINDOWS, DEBUG(WND, INFO, TRACE, STKGUARD, "DC_Test Project")
.const
r4_0 real4 0.0
r4_1 real4 1.0
r4_2 real4 2.0
r4_3 real4 3.0
r4_4 real4 4.0
r4_5 real4 5.0
r4_6 real4 6.0
r4_7 real4 7.0
r4_10 real4 10.0
r4_m10 real4 -10.0
.code
start:
SysInit
DbgClear ;Clears output window
finit
fld r4_7
fld r4_6
fld r4_5
fld r4_4
fld r4_3
fld r4_2
fld r4_1
fld r4_0 ;Levels = 8
DbgFPU
fdiv st(0), st(1)
DbgFPU
fdiv st(1), st(0)
DbgFPU ;st(1) = +inf
DbgLine
fcom r4_10
DbgFPU ;ST < Source
fcom r4_m10
DbgFPU ;ST > Source
fcom r4_0
DbgFPU ;ST = Source
fstp st(0)
fstp st(0)
DbgFPU ;Levels = 6
SysDone
invoke ExitProcess, 0
end start
and get the following output
FPU DUMP
FPU Levels : 8
Conditional: ST > Source
Exceptions : e s p u o z d i
st(0) = 0.0000E+0000
st(1) = 1.0000E+0000
st(2) = 2.0000E+0000
st(3) = 3.0000E+0000
st(4) = 4.0000E+0000
st(5) = 5.0000E+0000
st(6) = 6.0000E+0000
st(7) = 7.0000E+0000
FPU DUMP
FPU Levels : 8
Conditional: ST > Source
Exceptions : e s p u o z d i
st(0) = 0.0000E+0000
st(1) = 1.0000E+0000
st(2) = 2.0000E+0000
st(3) = 3.0000E+0000
st(4) = 4.0000E+0000
st(5) = 5.0000E+0000
st(6) = 6.0000E+0000
st(7) = 7.0000E+0000
FPU DUMP
FPU Levels : 8
Conditional: ST > Source
Exceptions : e s p u o Z d i
st(0) = 0.0000E+0000
st(1) = +Inf
st(2) = 2.0000E+0000
st(3) = 3.0000E+0000
st(4) = 4.0000E+0000
st(5) = 5.0000E+0000
st(6) = 6.0000E+0000
st(7) = 7.0000E+0000
????????????????????????????????????????????????????????????
FPU DUMP
FPU Levels : 8
Conditional: ST < Source
Exceptions : e s p u o Z d i
st(0) = 0.0000E+0000
st(1) = +Inf
st(2) = 2.0000E+0000
st(3) = 3.0000E+0000
st(4) = 4.0000E+0000
st(5) = 5.0000E+0000
st(6) = 6.0000E+0000
st(7) = 7.0000E+0000
FPU DUMP
FPU Levels : 8
Conditional: ST > Source
Exceptions : e s p u o Z d i
st(0) = 0.0000E+0000
st(1) = +Inf
st(2) = 2.0000E+0000
st(3) = 3.0000E+0000
st(4) = 4.0000E+0000
st(5) = 5.0000E+0000
st(6) = 6.0000E+0000
st(7) = 7.0000E+0000
FPU DUMP
FPU Levels : 8
Conditional: ST = Source
Exceptions : e s p u o Z d i
st(0) = 0.0000E+0000
st(1) = +Inf
st(2) = 2.0000E+0000
st(3) = 3.0000E+0000
st(4) = 4.0000E+0000
st(5) = 5.0000E+0000
st(6) = 6.0000E+0000
st(7) = 7.0000E+0000
FPU DUMP
FPU Levels : 6
Conditional: ST = Source
Exceptions : e s p u o Z d i
st(0) = 2.0000E+0000
st(1) = 3.0000E+0000
st(2) = 4.0000E+0000
st(3) = 5.0000E+0000
st(4) = 6.0000E+0000
st(5) = 7.0000E+0000
FPU Levels : 8
Conditional: ST > Source
Exceptions : e s p u o z d i
st(0) = 0.0000E+0000
st(1) = 1.0000E+0000
st(2) = 2.0000E+0000
st(3) = 3.0000E+0000
st(4) = 4.0000E+0000
st(5) = 5.0000E+0000
st(6) = 6.0000E+0000
st(7) = 7.0000E+0000
FPU DUMP
FPU Levels : 8
Conditional: ST > Source
Exceptions : e s p u o z d i
st(0) = 0.0000E+0000
st(1) = 1.0000E+0000
st(2) = 2.0000E+0000
st(3) = 3.0000E+0000
st(4) = 4.0000E+0000
st(5) = 5.0000E+0000
st(6) = 6.0000E+0000
st(7) = 7.0000E+0000
FPU DUMP
FPU Levels : 8
Conditional: ST > Source
Exceptions : e s p u o Z d i
st(0) = 0.0000E+0000
st(1) = +Inf
st(2) = 2.0000E+0000
st(3) = 3.0000E+0000
st(4) = 4.0000E+0000
st(5) = 5.0000E+0000
st(6) = 6.0000E+0000
st(7) = 7.0000E+0000
????????????????????????????????????????????????????????????
FPU DUMP
FPU Levels : 8
Conditional: ST < Source
Exceptions : e s p u o Z d i
st(0) = 0.0000E+0000
st(1) = +Inf
st(2) = 2.0000E+0000
st(3) = 3.0000E+0000
st(4) = 4.0000E+0000
st(5) = 5.0000E+0000
st(6) = 6.0000E+0000
st(7) = 7.0000E+0000
FPU DUMP
FPU Levels : 8
Conditional: ST > Source
Exceptions : e s p u o Z d i
st(0) = 0.0000E+0000
st(1) = +Inf
st(2) = 2.0000E+0000
st(3) = 3.0000E+0000
st(4) = 4.0000E+0000
st(5) = 5.0000E+0000
st(6) = 6.0000E+0000
st(7) = 7.0000E+0000
FPU DUMP
FPU Levels : 8
Conditional: ST = Source
Exceptions : e s p u o Z d i
st(0) = 0.0000E+0000
st(1) = +Inf
st(2) = 2.0000E+0000
st(3) = 3.0000E+0000
st(4) = 4.0000E+0000
st(5) = 5.0000E+0000
st(6) = 6.0000E+0000
st(7) = 7.0000E+0000
FPU DUMP
FPU Levels : 6
Conditional: ST = Source
Exceptions : e s p u o Z d i
st(0) = 2.0000E+0000
st(1) = 3.0000E+0000
st(2) = 4.0000E+0000
st(3) = 5.0000E+0000
st(4) = 6.0000E+0000
st(5) = 7.0000E+0000
Perhaps if you can post your code I can try to find out the problem.
Best regards,
Biterider
Hi Biterider,
With the help of your own output, I tested a little further.
The bottleneck seems to be when having used an empty register
as a source operand.
Hope this helps finding the bug on the level, and the contents part.
I think I misunderstood the meaning of the conditional line.
It doesn't always have a meaning in relation to the last instruction.
It just reflects the state of the conditional flags at that given time.
Am I right?
Friendly regards,
mdevries.
With the help of your own output, I tested a little further.
The bottleneck seems to be when having used an empty register
as a source operand.
%include @Environ(OA32_PATH)\\Code\\Macros\\Model.inc
SysSetup OOP_BASE, DEBUG(WND)
.data
f4 real4 1.5
f8 real8 2.0
f10 real10 0.5
f0 real4 -0.0
fn real4 3.0E-38
.code
start:
SysInit
DbgText " "
finit
DbgFPU "finit"
DbgText " "
fwait
DbgFPU "fwait"
DbgText " "
fldpi
DbgFPU "fldpi"
DbgText " "
fld f4
DbgFPU "fld f4"
DbgText " "
fld f8
DbgFPU "fld f8"
;Divide by -0.0
DbgText " "
fdiv f0
DbgFPU "fdiv f0"
;Divide by -0.0 again
DbgText " "
fdiv f0
DbgFPU "fdiv f0"
;Use infinity in a computation
DbgText " "
fsub f4
DbgFPU "fsub f4"
DbgText " "
fst f8
DbgFPU "fst f8"
DbgText " "
fstp f10
DbgFPU "fstp f10"
DbgText " "
fld fn
DbgFPU "fld fn"
;Divide by an empty register.
;
; This must be the bottleneck.
; If you comment the following 3 lines out,
; you will be able to see the contents of
; all the 8 registers in the end.
;
DbgText " "
fdiv st(0), st(7)
DbgFPU "fdiv st(0), st(7)"
DbgText " "
fld fn
DbgFPU "fld fn"
DbgText " "
fld fn
DbgFPU "fld fn"
DbgText " "
fld fn
DbgFPU "fld fn"
DbgText " "
fld fn
DbgFPU "fld fn"
DbgText " "
fld f4
DbgFPU "fld f4"
SysDone
invoke ExitProcess, 0
end start
Hope this helps finding the bug on the level, and the contents part.
I think I misunderstood the meaning of the conditional line.
It doesn't always have a meaning in relation to the last instruction.
It just reflects the state of the conditional flags at that given time.
Am I right?
Friendly regards,
mdevries.
Hi
Second try :)
I hope that it works now ;)
Regards,
Biterider
Second try :)
FPU_BUFFER struct
wControlWord word ?
wUnused0 word ?
wStatusWord word ?
wUnused1 word ?
wTagWord word ?
wUnused2 word ?
pInstruction dword ?
wCodeSegment word ?
wUnused3 word ?
pOperand dword ?
wDataSegment word ?
wUnused4 word ?
tSt0 tbyte ?
tSt1 tbyte ?
tSt2 tbyte ?
tSt3 tbyte ?
tSt4 tbyte ?
tSt5 tbyte ?
tSt6 tbyte ?
tSt7 tbyte ?
FPU_BUFFER ends
DbgOutFpu proc pDest:Pointer
local FPU_Buffer:FPU_BUFFER, dLevels:dword
local szBuffer[128]:byte
local szFloat[32]:byte
local szFPExept[30]:byte
fsave FPU_Buffer
invoke StrCopy, addr szFPExept, offset szDbgFPU6 ;Exceptions
mov ax, word ptr FPU_Buffer.wTagWord
xor ecx, ecx
.while ecx < 8
rol ax, 2
mov dx, ax
and dx, 0000000000000011b
.break .if dx == 0000000000000011b
inc ecx
.endw
mov dLevels, ecx
invoke wsprintf, addr szBuffer, offset szDbgFPU5, dLevels ;Display Levels found
invoke DbgOutText, addr szBuffer, $RGB(50,150,50), DBG_EFFECT_NEWLINE, pDest
movzx eax, word ptr FPU_Buffer.wStatusWord
shr eax, 6 ;ax = 000000X* XXY*Y*ZZ
shl al, 3 ;ax = 000000X* *Y*ZZ---
shl ax, 1 ;ax = 00000X** Y*ZZ----
shl al, 1 ;ax = 00000X** *ZZ-----
shr eax, 7 ;ax = -------0 0000X***
and eax, 7 ;ax = 00000000 00000***
.if( eax == 0 ) ;If ST > Source
mov ecx, offset szDbgFPU1 ; then say so
.elseif( eax == 1 ) ;If ST < Source
mov ecx, offset szDbgFPU2 ; then say so
.elseif( eax == 4 ) ;IF ST = Source
mov ecx, offset szDbgFPU3 ; then say so
.else ;Anything else
mov ecx, offset szDbgFPU4 ; Say as Undefined
.endif
invoke DbgOutText, ecx, $RGB(50,150,50), DBG_EFFECT_NEWLINE, pDest
movzx eax, word ptr FPU_Buffer.wStatusWord;eax = Status first found
xor ecx, ecx ;ecx = 0
lea edx, szFPExept ;edx = Exception String Address
add edx, 13 ;edx = First Exception Bit
.while ecx < 8 ;Go thru 8 exception bits
rol al, 1 ;Rol the exception bits left 1
jc @F ;See if a '1' Passed out
or byte ptr , 20h ;No, then force lower case (not set)
jmp @next ; and onto next section
@@:
and byte ptr ,0DFh ;Yes, then Force Upper case (Exception set)
@next: ;and onto next section
add edx, 2 ;Since Spaces, inc 2 in string
inc ecx ;Next bit!
.endw
invoke DbgOutText, addr szFPExept, $RGB(50,150,50), DBG_EFFECT_NEWLINE, pDest
xor esi, esi ;esi = Counter = 0
lea edi, FPU_Buffer.tSt0
.while esi < dLevels ;Go thru all known stack entries
finit
fld tbyte ptr
invoke St0ToStr, addr szFloat, 0, 4, f_SCI ;Create Text Strings from them
invoke wsprintf, addr szBuffer, offset szDbgFPU7, \ ;And display their contents
esi, addr szFloat
invoke DbgOutText, addr szBuffer, $RGB(50,150,50), DBG_EFFECT_NEWLINE, pDest
add edi, sizeof tbyte ;Next entry
inc esi
.endw
ret
DbgOutFpu endp
I hope that it works now ;)
Regards,
Biterider
Hi Biterider,
It's working now. Thanks again!
Friendly regards,
mdevries.
It's working now. Thanks again!
Friendly regards,
mdevries.