📄 appendix b the salvm instruction set.htm
字号:
<B>Figure {EESORD}</B> An example of pushing data onto the EES in the order
that it appears in the equation.
</PRE>Some of these instructions bear a little explanation. For instance, the
modulus operator does not work correctly for all implementations. Modulus (or
remainder) is mathematically defined such that <TT>(a/b)*b + a mod b = a</TT>,
for <I>all</I> <TT>a</TT> and <TT>b</TT>. For some implementations of modulus,
this holds true only when a and b are positive. This comes as a shortcomming of
2's compliment arithmetic, and is the only real disadvantage of this
representation. The SALVM uses the mathematical definition of modulus. Remember
then, that modulus in the SALVM is a little slow.
<P>Although <TT>A MODx B</TT> finds the remainder of <TT>A DIVx B</TT>, the
<TT>FMODx</TT> instruction is something a little different. For one thing, this
instruction only works on one operand. If A is positive, <TT>FMODx A</TT> will
return the portion of A between (1, 0]. If A is negative, it will return the
portion of A within the interval [0, -1).
<P>The <TT>FTRNCx</TT> instruction works opposite the <TT>FTRNCx</TT>
instruction. If A is positive, <TT>FTRNCx A</TT> will return the portion of A
greater than or equal to 1. If A is negative, it will return the portion of A
less than or equal to -1. Mathematically, <TT>FTRNC A + FMOD A = A.</TT>
<P>All of the other instructions should be familiar, and no further explanation
should be required.
<P>
<H2>B.3 Increment and Decrement Instructions</H2><!-------------------------------------------------------------------------------->There
is also a set of instructions for incrementing and decrementing a value on the
EES. These instructions do not consume their operand, they merely increment or
decrement. They are listed in table {INCDEC}
<P><PRE> Data Type(s) bits increment decrement
=================================================
(un)signed byte 8 INCB DECB
(un)signed word 16 INCW DECW
(un)signed dword 32 INCD DECD
(un)signed qword 64 INCQ DECQ
single precision 32 FINCS FDECS
double precision 64 FINCD FDECD
tenbyte precision 80 FINCT FDECT
quad precision 128 FINCQ FDECQ
<B>Table {INCDEC}</B> This table shows all of the increment and decrement
instructions.
</PRE>As an example, <TT>FDECD</TT> will take the top 8 bytes on the EES, treat
it as a double precision float, and increment it, leaving the result on the EES.
See figure {INCDECF} <PRE>
| 3.5 | | 4.5 |
| | --> FINCx --> | |
| ... | | ... |
|_______| |_______|
EES EES
Before After
<B>Figure {INCDECF}</B> A representation of the way the increment and
decrement instructions work.
</PRE>
<H2>B.4 Bit Operation Instructions</H2><!-------------------------------------------------------------------------------->The
bitwise instructions within the VM are organized into two groups. All groups
work on data sizes ranging from 8 to 64 bits. The first group performs the four
logical operations: and, or, exclusive or, and not. The second group performs
bit shifts (signed and unsigned), and bit rotations. <PRE> Signed
Shift Shift Shift Rotate Rotate
Data Type(s) bits And Or Xor Not Left Right Right Left Right
=====================================================================================
(un)signed byte 8 ANDB ORB XORB NOTB SHLB USHRB SSHRB ROLB RORB
(un)signed word 16 ANDW ORW XORW NOTW SHLW USHRW SSHRW ROLW RORW
(un)signed dword 32 ANDD ORD XORD NOTD SHLD USHRD SSHRD ROLD RORD
(un)signed qword 64 ANDQ ORQ XORQ NOTQ SHLQ USHRQ SSHRQ ROLQ RORQ
<B>Table {SHFROT}</B> The bit shift and rotate instructions.
</PRE>These instructions all work the same way that the arithmetic instructions
work. Remember that the operands must be pushed in the order that they appear.
The <TT>NOTx</TT> instruction takes only one operand. All of the others take
two. For example, the <TT>ANDW</TT> will take two words from the EES, and them
together, and store the result on the EES as a word.
<P>The shift and rotate instructions are a little different in that they only
require one byte to designate the distance to shift. These will take a byte from
the top of the EES, and shift/rotate the underlying quantity of bytes. For
instance, <TT>ROLQ</TT> will take a byte and a quadword from the EES (the byte
is on the top and the qword underneath), left-rotate the quadword by the number
in the byte, then store the rotated quadword on the EES. <PRE>
| [byte]| |[-shifted--|
|[-quadword-| |-quadword-]|
|----------]| --> ROLQ --> | |
| | | |
| ... | | ... |
|___________| |___________|
EES EES
Before After
<B>Figure {SREXMP}</B> An example of how the shift and rotate instructions
work.
</PRE>
<H2>B.5 Conversion Instructions</H2><!-------------------------------------------------------------------------------->The
reader has probebly noticed so far that all instructions work on one and only
one type of data. This is true. Since this is the case, the need for data
conversion arises. The SALVM has instructions for just this task. There are two
types of conversion instructions. The first type converts between levels of
precision, like from a byte to a word, or from a single precision to a double
precision. The second type converts from one data type to another, like integer
to real. Among both groups, there exist a couple or so instructions, which are
for conversions that are very commonly performed.
<P>
<H3>B.5.1 Precision Conversion</H3><!-------------------------------------------------------------------------------->Precision
conversion is a very common task in most languages. The precision conversion
instructions take one operand on the EES, and one immediate byte as a parameter
that tells what type of conversion is to be performed. See table {CONV}. <PRE> Op-Code Meaning
============================================
UCNV Convert an unsigned integer
SCNV Convert a signed integer
FCNV Convert a floating point number
<B>Table {CONV}</B> The conversion op-codes.
</PRE>These instructions have no direct way of telling what quantity to start
out with, and what quantity to emd up with, so they require an immediate
parameter. The parameter is a single byte, where the most significant nibble
designates the quantity of bytes to start with, and the least significant nibble
designates the quantity of bytes to convert to. The values of each nibble and
the type represented are listed in table {NIBVAL}.
<P><PRE> Nibble
Value Size represented
==================================
0 card8
1 card16
2 card32
3 card64
4 int8
5 int16
6 int32
7 int64
8 real32
9 real64
A real80
B real128
<B>Table {NIBVAL}</B> Values of each nibble for precision conversion.
</PRE>You might notice that the first five values represent <TT>2^n</TT> bytes.
The last one was given an arbitrary value, since for <TT>2^n = 10</TT>, n is not
an integer.
<P>As an example, to convert a single precision float to a quad precision float,
the instruction would be formatted like figure {PCFORM}. <PRE> -------------------------
... | FCNV | 8B | ...
-------------------------
<B>Figure {PCFORM}</B> Example to convert a single precision float on the
EES to a quad precision float.
</PRE>All of the precision conversion instructions in table {CONV} work in this
manner.
<P>In addition to these three instructions, there are a handful of instructions,
which are optimized versions of the above. These instructions represent the most
common conversions that are encountered. They are listed in table {COMCNV}. <PRE> Intruction Meaning
===========================================
BTOD byte to dword
DTOB dword to byte
WTOD word to dword
DTOW dword to word
FSTOFD single precision to double precision
FDTOFS double precision to single precision
<B>Table {COMCNV}</B> These are the most common conversions.
</PRE>These conversions are most common because they involve conversions to and
from the default types in SAL. In SAL, an <TT>int</TT> defaults to 32 bits, and
a <TT>real</TT> defaults to double precision.
<P>These instructions take no immediate parameters, and each one was crafted to
perform explicitly one type of conversion.
<P>Notice that whenever converting data from a higher level of precision to a
lower level of precision, there is a possible loss of data.
<P>
<H3>B.5.2 Data Type Conversion</H3><!-------------------------------------------------------------------------------->Data
type conversion involves a slightly different kind of conversion, e.g.,
conversion from int to real, or vice versa. Here they are in table {TCONV} <PRE> Op-Code Meaning
============================================
STOF Signed integer to float
FTOS Float to signed integer
UTOF Unsigned integer to float
FTOU Float to unsigned integer
<B>Table {TCONV}</B> The data conversion instructions.
</PRE>These instructions function in a similar manner as the ones for precision
conversion. They all take a byte that describes the precision to convert from
and the precision to convert to. See table {NIBVAL}. Let's say we want to
convert a signed word to a double precision value (real64). We would format the
instruction as shown in figure {DCFORM} <PRE> -----------------------
... | STOF | 59 | ...
-----------------------
<B>Figure {DCFORM}</B> Example converting a word to a double precision
value.
</PRE>Like the precision conversion op-codes, the data type conversion op-codes
have some optimized siblings. These are listed in table {COMTCNV} <PRE> Intruction Meaning
===========================================
DTOFD Signed dword to double precision real
FDTOD Double precision real to signed dword
<B>Table {COMCNV}</B> These are the most common conversions.
</PRE>Since we are using a 2's compliment architecture, it would not make a lot
of sense for there to be instructions that convert between signed and unsigned
integers. Also, notice that only positive real numbers will correctly convert to
an unsigned integer. In that case, the sign gets truncated.
<P>
<H2>B.6 Bit Comparison Instructions</H2><!-------------------------------------------------------------------------------->The
comparison instructions for the VM return a byte containing either a 0 or a 1
depending upon whether or not the comparison was true. They are listed in table
{COMPINS}. <PRE> Data
size = <> > < >= <=
===============================================
byte EQLB NEQB GTRB LESB GEQB LEQB
word EQLW NEQW GTRW LESW GEQW LEQW
dword EQLD NEQD GTRD LESD GEQD LEQD
qword EQLQ NEQQ GTRQ LESQ GEQQ LEQQ
<B>Table {COMPINS}</B> The comparison instructions.
</PRE>These instructions actually work in two steps. The first step is to
compare the two quantities of data, and the second is to evaluate the comparison
to see if the result was true.
<P>The method of comparison assumes a 2's compliment host architecture. The
comparison of A to B is done by subtracting B from A (A-B). Using this
technique, it becomes irrelevant whether the integer is signed or unsigned. This
is one of the beauties of 2's compliment. Also, floating point numbers can be
compared in the same way, since their format is such that their relationship can
be easily determined without using special operations. That is, if A and B are
floating point numbers, and A is less than B, the binary representation of A and
B will be such that A is less than B for all A and B. The same holds for all
relations with real numbers. In short, what we have is a method for comparing
quantities of data without reguard to their format, whatsoever. To compare A to
B, all we need is for A to be the same size and type as B, and we subtract B
from A, and the result is a signed integer, where a result that is less than 0
means A is less than B, a result that is greater than zero means that A is
greater than B, and a result that is equal to zero means that A is equal to B.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -