Rocksolid Light

Welcome to novaBBS (click a section below)

mail  files  register  nodelist  faq  login

//GO.SYSIN DD *, DOODAH, DOODAH


programming / comp.lang.asm.x86 / Re: FPU (x87) code debugging.

Subject: Re: FPU (x87) code debugging.
From: Robert Prins
Newsgroups: comp.lang.asm.x86
Organization: A noiseless patient Spider
Date: Sun, 8 Aug 2021 11:26 UTC
References: 1 2 3 4 5
Path: i2pn2.org!i2pn.org!eternal-september.org!reader02.eternal-september.org!.POSTED!not-for-mail
From: rob...@nospicedham.prino.org (Robert Prins)
Newsgroups: comp.lang.asm.x86
Subject: Re: FPU (x87) code debugging.
Date: Sun, 8 Aug 2021 11:26:25 +0000
Organization: A noiseless patient Spider
Lines: 249
Approved: fbkotler@myfairpoint.net - comp.lang.asm.x86 moderation team.
Message-ID: <seo80b$ro2$1@dont-email.me>
References: <sejqg6$c32$1@gioia.aioe.org> <sem4pa$1rv$1@gioia.aioe.org>
<sema6s$g37$1@gioia.aioe.org> <senimi$ei6$1@gioia.aioe.org>
<seo3k6$1m23$1@gioia.aioe.org>
Mime-Version: 1.0
Content-Type: text/plain; charset=utf-8; format=flowed
Content-Transfer-Encoding: 7bit
Injection-Info: reader02.eternal-september.org; posting-host="e80ba3c5c46afa3bb9fe4eb7bea769c3";
logging-data="29256"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX18zMVTXCj6EGBV4h5NtA4QiymJPZQ0XdOE="
User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:78.0) Gecko/20100101
Thunderbird/78.12.0
Cancel-Lock: sha1:8edMRYbUUGbjI5hi4QNAqLa6d34=
View all headers
On 2021-08-08 08:11, R.Wieser wrote:
Robert,

It might have some safeguards against executing data :)

I've used the "trick" before, so I don't think so.  Currently I'm torn
between the posibilities that the processor I'm using might not be having
that command, that I'm simply bungling up or that there is some kind of
memory alignment involved (the latter one would not be the first time I've
run into it).

Is there any possibility you could take a look at and post what code gets
generated for an "FXSAVE {register pointer}" ?

I don't get that - why only the first one, and why would
it clobber (the value at) the stack top ?

The stack is eight FP registers, any load pushes the one
on the top into the bit bucket.

True.  But such a push would only clobber anything if the (circular) stack
is completely full.

Actually, I believe the registers are a circular file,

It has to be, as my example code works : after the second FLD1 the TOS is 6.
But I can still execute a FSTP ST(2) ,which seemingly points at 6+2 = 8.

and the load overwrites and decrements TOS.

The info to, for instance, FLD mentions decrementing first, than store
(which is why I didn't understand your "clobbering" remark).

Aren't those three bits (0-7) the Top-of-Stack pointer?

Yep.    I was assuming that that value would (implicitily) tell me how many
values where placed on the stack.   Turns out it doesn't.   :-\

People sometimes compare the FPSW with the x86 flags register.
It is not.

Similar perhaps (both contain status flags), but (ofcourse) not the same.

34 years ago I wrote an extention to MS-DOS DEBUG.COM
to examine the x87.

I'm not sure what you mean with an 'extension' (wasn't aware that Debug
supported such a thing), but years ago I wrote something for it (using
memory patching) so it could deal with a few more opcodes.

Converting binaryFP to decimal FP was hard.

Thats something I still have to take a look at.  Just not at this moment.

You still haven't told us what OS (DOS, Windoze, Linux) or CPU (32/64 bit) you're running this code on....

David Lindauer's GRDB (DOS) can show the contents of FPU registers, and as you are/were a Pascal user, so can, I think Delphi. Virtual Pascal can definitely do it, I use the (sadly) wrapping code below:

{************** Copyright (C) Robert AH Prins 2018-2018 ****************
*                                                                      *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 3, or (at your option)  *
* any later version.                                                   *
*                                                                      *
* This program is distributed in the hope that it will be useful,      *
* but WITHOUT ANY WARRANTY; without even the implied warranty of       *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the        *
* GNU General Public License for more details.                         *
*                                                                      *
* You should have received a copy of the GNU General Public License    *
* along with this program; if not, write to the Free Software          *
* Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA   *
************************************************************************
+------------+---------------------------------------------------------+
| Date       | Major changes                                           |
+------------+---------------------------------------------------------+
|            |                                                         |
+------------+---------------------------------------------------------+
| 2018-09-30 | Add x_int3 to selectively enable debug code             |
+------------+---------------------------------------------------------+
| 2018-08-31 | Initial version                                         |
+------------+---------------------------------------------------------+
************************************************************************
*                              DEBUG.PAS                               *
*                                                                      *
* This unit contains some code that enables viewing of extended (XMM & *
* YMM) registers in various formats.                                   *
***********************************************************************}
unit debug;

{============================} interface {=============================}
const x_int3: boolean = false;

type
   r_fpu = record                                                 {   16}
             st : extended;
             zz : array [0..5] of byte;
           end;

   r_mmx = record                                                 {   16}
             case integer of
               1: (_by: array [0..7] of byte;
                   z1 : array [0..7] of byte);
               2: (_in: array [0..3] of shortint;
                   z2 : array [0..7] of byte);
               3: (_lo: array [0..1] of longint;
                   z3 : array [0..7] of byte);
               4: (_si: array [0..1] of single;
                   z4 : array [0..7] of byte);
               5: (_do: array [0..0] of double;
                   z5 : array [0..7] of byte);
               6: (_ch: array [0..7] of char;
                   z0 : array [0..7] of byte);
           end;

   r_xmm = record                                                 {   16}
             case integer of
               1: (_by: array [0..15] of byte);
               2: (_in: array [0.. 7] of shortint);
               3: (_lo: array [0.. 3] of longint);
               4: (_si: array [0.. 3] of single);
               5: (_do: array [0.. 1] of double);
               6: (_ch: array [0..15] of char);
           end;

   xsave_hdr = array [0..63] of byte;                             {   64}

   fpu   = array [0..7] of r_fpu;                                 {  128}
   mmx   = array [0..7] of r_mmx;                                 {  128}
   xmm   = array [0..7] of r_xmm;                                 {  128}

   xsptr = ^a_xs;
   a_xs  = record
             case integer of
               1: (legacy   : array [0..159] of char;             {  160} // raw legacy data
                   xmm_32   : xmm;                                {  128} // XMM0-7  (low part of YMM0-7)
                   xmm_64   : xmm;                                {  128} // XMM8-15 (low part of YMM8-15) (AMD64)
                   xsave_hdr: xsave_hdr;                          {   64} // Storage bitmap for additional data
                   ymm_32   : xmm;                                {  128} // YMM0-7  (high part, low in XMM0-XMM7)
                   ymm_64   : xmm);                               {  128} // YMM8-15 (high part, low in XMM8-XMM15) (AMD64)

               2: (fcw      : smallword;                          {    2} // x87 FPU control word
                   fsw      : smallword;                          {    2} // x87 status word
                   ftw      : byte;                               {    1} // x87
                   res_1    : byte;                               {    1}
                   fop      : smallword;                          {    2} // x87 last opcode
                   fip      : longint;                            {    4} // x87 EIP
                   fcs      : smallword;                          {    2} // x87 CS:
                   res_1_x64: smallword;                          {    2} // + previous: RIP (AMD64)
                   fdp      : longint;                            {    4} // x87 data pointer
                   fds      : smallword;                          {    2} // x87 DS:
                   res_2_x64: smallword;                          {    2} // + previous: DIP (AMD64)
                   mxcsr    : longint;                            {    4} // SSE control word
                   mxcsr_msk: longint;                            {    4}

                   case integer of
                     3: (fpu: fpu);                               {  128} // x87 FPU registers
                     4: (mmx: mmx));                              {  128} // x86 MMX registers

               3: (raw      : array [0..1023] of byte);           { 1024} // just raw data
             end;

procedure xsave;

{==========================} implementation {==========================}

{***********************************************************************
* XSAVE:                                                               *
*                                                                      *
* Save the entire processor state for debugging purposes               *
***********************************************************************}
procedure xsave; assembler; {&uses none} {&frame+}
var xs: array [0..2047] of char;
var xp: xsptr;

asm
   //a-in xsave
   cmp     x_int3, true
   jne     @99

   pushad

   //------------------------------------------------------------------
   // clear out save area
   //------------------------------------------------------------------
   lea     edi, xs
   xor     eax, eax
   mov     ecx, type xs / 4
   rep     stosd

   //------------------------------------------------------------------
   // save area must be aligned on 64-byte boundary
   //------------------------------------------------------------------
   lea     edi, xs
   add     edi, 63
   and     edi, -64
   mov     xp, edi

   //------------------------------------------------------------------
   // save everything that can be saved
   //------------------------------------------------------------------
   or      eax, -1
   or      edx, -1
{ xsave   [edi]       }  db    $0f,$ae,$27

   //------------------------------------------------------------------
   // display data in "Watches" window
   // - xp^          : all
   // - xp^.fpu      : all FPU registers as extended
   // - xmm_32[0]._lo: contents of XMM0 as 4 longints
   // - etc...
   //------------------------------------------------------------------
   int   3

   popad

@99:
   //a-out
end; {xsave}

end.

Robert
--
Robert AH Prins
robert(a)prino(d)org
The hitchhiking grandfather - https://prino.neocities.org/indez.html
Some REXX code for use on z/OS - https://prino.neocities.org/zOS/zOS-Tools.html



SubjectRepliesAuthor
o FPU (x87) code debugging.

By: R.Wieser on Fri, 6 Aug 2021

35R.Wieser
rocksolid light 0.7.2
clearneti2ptor