It is
the responsibility of the coder to apply the operations to
the correct data types.

Occasionally,
it is proper to apply a different (and apparently
inconsistent) operation to a data type.Consider the following.

XX DSDDouble-precision floating
point

All
that really says is “Set aside an eight–byte memory area, and
associate it with the symbol XX.”

Any eight–byte data item could be placed here,
even a 15–digit packed decimal format.(This is commonly done)

Reading Some BAD Assembler Text

To
show what could happen, and commonly does in student programs,
lets rewrite the above fragment.

LD0,XLOAD REGISTER 0 FROM
ADDRESS X

AD0,YADD VALUE AT ADDRESS Y

STD 0,ZSTORE RESULT INTO ADDRESS Z

XDCE‘3.0’SINGLE-PRECISION FLOAT, 4
BYTES

YDCE‘4.0’ANOTHER SINGLE-PRECISION

ZDCD‘0.0’A DOUBLE PRECISION

The
first instruction “LD0,X” will go to address X and extract the next
eight bytes.This will be four bytes for
3.0 and four bytes for 4.0.

The
value retrieved will be 0x4130
0000 4140 0000,
which represents
a double–precision number with value slightly larger than 3.0.

Had X
and Y been properly declared, the value retrieved would have been 0x4130 0000 0000 0000.

What A Modern Compiler Does

Consider
the following fragments of Java code.

double x = 3.0;// 64 bits or eight bytes

double y = 4.0;// 64 bits or eight bytes

double z = 0.0;// 64 bits or eight bytes

// More
declarations and code here.

z = x + y;// Do the addition that is// proper for this data
type.

// Here, it is
double-precision// floating point
addition.

Note
that the compiler will interpret the source–language statement
“z = x + y” according to the data
types of the operands.

Rereading the Java Text

Here
is an informal translation of the Java code.We assume that the Java
compiler is multi–pass, and that it has a standard first pass.

The
standard first pass will identify all of the symbols, allocate storage for
each, and assign a data type for each.

The
compiler, as a system program with input and output, maintains a number
of internal tables to assist in generating the appropriate code.

Here
is our reading.We assume a table used
to describe the variables.
For each variable, this table stores:the
character representation, the
storage location allocated, and the
data type for the variable.

When
an operation on a variable is called for, it is the description stored
in this compiler table that is used to select the proper low–level code.

Rereading the Java Text (page 2)

Let’s
begin by rereading and interpreting the code we have seen.

double x =
3.0;
// Allocate 8 bytes of storage to be associated with
// the symbol “x”.Initialize the value
to the
// double–precision floating–point value 3.0.
// Place entries in the compiler tables allocating
// eight bytes for storage and indicating that this
// variable is double–precision floating point.

IMPORTANT POINTThe
assembler code emitted is entirely dependent on the data types for
the operands, as declared earlier in the program.

Another
Note:When possible, the compiler will
avoid immediate reuse of registers,
in an attempt to keep as much data in local registers for
later use.The code is more efficient.

Side Note: How to Write a Better Compiler

Consider
the following Java fragment, focusing on how it might be
compiled and how it should be compiled.

double v = 0.0, w =
0.0, x = 3.0, y = 4.0, z = 5.0 ;

w = x + y ;

v = x + y + z ;

The
example below shows inefficient code of the type actually emitted by an
early 1970’s era compiler.The modern
compiler keeps the sum x
+ y in
register 0 and reuses it as a partial sum in the next result x + y + z.

Older CompilerModern
Compiler

LD0, XLD0, XAD0, YAD0, YSTD 0, WSTD 0, W

LD0, XAD0, YAD0, ZAD0, ZSTD 0, VSTD 0, V

A Final Comment on Assembler Addresses

Here
is some code that will work, though it is strange.

LD0,XLOAD REGISTER 0 FROM
ADDRESS X

AD0,YADD VALUE AT ADDRESS Y

STD 0,ZSTORE RESULT INTO ADDRESS Z

LD2,ZRESULT NOW IN REGISTER 2

XDCD‘3.0’DOUBLE-PRECISION FLOAT: 8
bytes

YDCD‘4.0’DOUBLE-PRECISION FLOAT: 8
bytes

ZDCF32-BIT INTEGER: 4 BYTES

Z1DCH16-BIT INTEGER: 2 BYTES

Z2DCH16-BIT INTEGER: 2 BYTES

The
code above will work.At the end,
register 2 will have the correct result.

What
about the strange declarations for Z, Z1, and Z2?All that matters is
that the STD 0,Z instruction has eight
contiguous bytes into which to place
its result so that the LD
2,Z
instruction can retrieve it.This is
done.

Summary

The
most obvious conclusion is that it is not appropriate to discuss
assembler language code in terms of variables.

The
name “variable” should be reserved
for higher–level compiled
languages in which a data type is attached to each data symbol.