HP3000-L Archives

March 1999, Week 1

HP3000-L@RAVEN.UTC.EDU

Options: Use Monospaced Font
Show Text Part by Default
Show All Mail Headers

Message: [<< First] [< Prev] [Next >] [Last >>]
Topic: [<< First] [< Prev] [Next >] [Last >>]
Author: [<< First] [< Prev] [Next >] [Last >>]

Print Reply
Subject:
From:
John Korb <[log in to unmask]>
Reply To:
John Korb <[log in to unmask]>
Date:
Wed, 3 Mar 1999 11:55:46 -0500
Content-Type:
text/plain
Parts/Attachments:
text/plain (219 lines)
Ted:

The byte to word address translation is what is causing the confusion.

Those of us who wrote SPL procedures to be called from BASIC became very
familiar with the address translation problem very quickly.

At the bottom of page F-4 and on page F-5 of the "Systems Programming
Language Reference Manual" is a description of the byte to word address
translation problem and some sample code which takes care of the problem.

As the text points out, the problem is that it is possible to have a byte
address which points to the DB-minus area, but that it is also possible
that a byte address points to a very large DB-plus address - an address
greater than can be expressed as a signed, 2s complement integer.  Think of
how the stack looks.


Register     Area
--------     ----

          +----------------------+
          | PCBX Area            |
   DL     +----------------------+  DL+0
          | User DL Area         |
          |----------------------|        (DB-minus area,
          | Subsystem DL Area    |         DL-plus area)
          | (VPlus, etc.)        |
   DB     +----------------------+  DB+0
          | Global Variable      |
          | Storage              |
          |                      |
   QI     +----------------------+  Initial Q location
          | Stack markers,       |
          | procedure local      |
          | variables            |
   Q      +----------------------+  Q   Last stack marker
          | Local variables for  |
          | the current          |
          | procedure            |
   S      +----------------------+  S   Top of Stack
          | Unused space at the  |
          | top of stack, area   |
          | into which the       |
          | current procedure    |
          | or procedures it     |
          | calls can expand     |
   Z      +----------------------+  Z   Stack Limit
          | A 128 word stack     |
          | overflow area        |
          | reserved for error   |
          | handling and stack   |
          | overflows            |
          +----------------------+

Now, consider the size of the stack.  It fits into an extra data segment,
and can be 32,764 words in size.  Some of that space is reserved for MPE
use (the PCBX area) so the available space (from your program's
perspective) is less than 32,764 words - and in most cases is 31,232 words
or less.

If the addressable range of the stack is 31,232 words, how many bytes is that?
Twice as many bytes, right?  So that means the byte addresses cover a range
of 62,464 bytes...in a 16 bit integer word.  Okay, that means that those
62,464 byte address range must be mapped into an integer address space that
spans from -32,768 through +32,767.

Now further assume that you have not allocated any DL to DB area, so the DB
register is near the base of the stack's extra data segment, and that you
have declared many arrays - say 24,000 words worth.  Most of your stack is
now in the DB to initial Q region, and is global storage.  To access these
global variables, DB relative addressing will be used.

Assume that at DB+22,000 (decimal) is a LOGICAL ARRAY named WORK which is
your print buffer.  The word address is simple ... +22,000.  The byte
address should be twice that value, or ... Oops!  It is greater than
32,767, the largest integer.  Okay, so what if it is treated as an unsigned
integer (or logical, in other words).  The value would be 44,000.  But, use
that value for addressing and it becomes the integer -21,536!

Okay, byte addresses can be negative, so that COULD be a DB-minus address.
But byte addresses can be greater than 32,767 also, in which case the
address needs to be treated as an unsigned value rather than a signed
value.  So how do you know which?  You use the "S" register, as explained
on page F-5 of the manual.

In your case the problem is going from a byte address that is expressed as
a negative integer, to an integer word address.  Your byte address is so
large that while it looks like a negative number, it is really treated as
an unsigned integer.  Using the above addresses as an example, your stack might
be laid out something like this:

                   DB Relative Addresses
                   ---------------------
                            2s   Unsigned
                           Comp     Int
                   Word    Byte    Byte
Register           Addr    Addr    Addr
--------          ------  ------  ------

XDS Base +------+   -512   -1024   -1024
         |      |
   DL    +------+    -88    -176    -176
         |      |
   DB    +------+      0       0       0
         |      |
         |      |
         |      |
         |      |
         |------|
         | Work |  22000  -21536   44000
         | Array|
         |      |
         |------|
         |      |
   Q     +------+  22136  -21264   44272
         |      |
   S     +------+  22142  -21252   44284
         |      |
   Z     +------+  23330  -18876   46660
         |      |
         +------+

Your situation is very similar to that of the variable at word address
+22,000 in the above example.  Assume for a moment that the byte address
you have is the same as in the above example, and when expressed as an
integer is -21,536.  When you divide by two to get the word address (using
the ASR instruction used with 2s complement integer operations), you get
-10,768.

When -10,768 is used as the word address, it points somewhere not only in
the DB-minus area, but so far below DB that it goes below the DL register,
below the PCBX area, and off the bottom of the extra data segment.
Obviously a bounds violation.

However, if you take the -21,536 address and instead of performing an
integer divide by two perform a logical/unsigned divide by two operation
(using the LSR instruction and treating the -21,536 value as the unsigned
integer 44,000), you get +22,000, a valid address in the DB-plus area.

The trick is to know whether the byte address is in the DB-plus area or in
the DB-minus area.  The code on page F-5 will take care of the problem for you.

In summary:

  o  If the byte address is in the DB-plus area,
     you must use LSR to calculate the proper word address.

  o  If the byte address is in the DB-minus area,
     you must use ASR to calculate the proper word address.
     (if you come up with a DL-DB area so large that the negative
     byte address wraps around, expect more problems)

Whenever possible, use a native word address rather than calculating the
word address.  The same goes for byte addresses.  That is why declarations
like:

   Logical Array    LBuf(0:127);
   Byte Array       BBuf(*)=LBuf;

are so often found in SPL programs.  The work of calculating the correct
address to use is dumped on the SPL compiler (which knows whether where the
variable is located), and there is far less chance of an addressing error.


Hope the explaination helps,

John


At 3/3/99 09:44 AM , you wrote:
>Thus it was written in the epistle of Frank McConnell,
>> FREAD expects you to give it a logical array, so hand it WORKL
>> instead of WORK.
>>
>> At least for SPL on the classic (meaning I have no idea how this works
>> when Splash! and/or PA-RISC 3000s are involved), when you call an
>> intrinsic that expects a word pointer but give it a byte pointer, the
>> compiler inserts an arithmetic shift right (ASR) to convert the byte
>> pointer to a word pointer (and should give you a warning to tell you
>> that it's been so helpful).  ASR preserves the sign bit, so if the
>> value of the byte pointer is negative, so will be the value of the
>> word pointer.  (Also, if the byte pointer is odd (not word-aligned),
>> the least significant bit will get lost, so the resulting word pointer
>> will likely point one byte off from your byte pointer.)
>
>Ok, I'm confused.  At least the code seems to have tried to do the right thing
>with FREAD.  It *is* passing a word address or what is trying to be a word
>address.  I'm sorry for miswriting in my original post.  However this ASR vs.
>LSR thing has got me confused.  In the SPL manual (the December, 1976 version,
>p 4-3), it claims, "All addresses are signed, one-word integers and are
>treated as such in expressions."  However, when @WORK was negative, passing
>@WORK & ASR(1) to FREAD gave me a bounds violation, but passing @WORK & LSR(1)
>gave me good results.  From that, it seems that addresses are *unsigned*. So
>what's up wid dat?
>
>Ted
>--
>Ted Ashton ([log in to unmask]), Info Serv, Southern Adventist University
>          ==========================================================
>[Of her:]
>Her statistics were more than a study, they were indeed her religion. . . .
>she held that the universe -- including human communities -- was evolving in
>accordance with a divine plan; that it was man's business to endeavor to
>understand this plan and guide his actions in sympathy with it. But to
>understand God's thoughts, she held we must study statistics, for these
are the
>measure of His purpose. Thus the study of statistics was for her a religious
>duty.
>                        -- Nightingale, Florence (1820-1910)


--------------------------------------------------------------
John Korb                            email: [log in to unmask]
Innovative Software Solutions, Inc.

The thoughts, comments, and opinions expressed herein are mine
and do not reflect those of my employer(s), or anyone else.

ATOM RSS1 RSS2