In the Classic HP 3000 architecture, you must be extremely careful of conversions from byte addresses to word addresses and vice versa, because of negative stack addressing which makes byte addresses ambiguous. Hewlett-Packard designed the original MPE machine as a 16-bit word machine, with bytes added on as an embellishment. Even though the current MPE/iX machines use the 32-bit PA-RISC chips, the old 16-bit design occasionally still bites.
A Classic byte address in the stack can range from a minimum of -64 kilobytes (KB) to a maximum of +64 KB, for a potential address range of 128 KB. However, since there are only 16 bits for a byte address, each 16-bit address value can either be a negative or positive address, depending upon the current settings of the DL and Z registers.
This weird machine design leads to numerous programming problems. For example, SPL can unambiguously equivalence a byte array to an integer array, but never the other way around.
Therefore, never pass an SPL byte array as an actual parameter when a procedure expects a word array. If you just have to do so, first move the byte data to another byte array that is equivalenced to a word array and pass the word array, or go back and redo your declarations. If your SPL compile generates an "Arithmetic Right-Shift" warning, you have violated this rule and may not be passing the array you think you are.
Never initialize SPL word pointers with byte addresses; it won't work and the compiler does not give a warning.
Use SPL indexing rather than address arithmetic:
The first does proper boundary calculations for
negative addresses, but the second just does an Integer Add.
If you must add or subtract byte addresses,
use Logical arithmetic, not Integer:
len := tos - logical(@buf), or
let the Move or Scan statement compute the length as in
len := (move buf := buf while n).
None of this is a problem on a PA-RISC MPE machine unless you are executing in Compatibility Mode.