10.2. Predefined Functions and Procedures.   

 import local.units.sdsu.io.*;

import java.lang.*;
import java.io.*;
public class Simple
{
public static void main(String argv[]) throws IOException
{
Format.print(System.out,"HELLO WORLD\n");
}
}

How does Format.print(System.out,"HELLO WORLD\n"); fit into Java SYNTAX? It is obviously part of STATEMENT!


 

Java_statement.eps
These routines = standard procedures (and functions such as sin, cos, ord, trunc) are not normally part of the compiler. It does not produce the code to handle the writing out of our message. It calls a procedure which has been compiled separately before hand. It produces code not unlike PL0 which in a naive fashion says:

STOre the string (or its address) on the stack
CALL print /* print out data */
What address goes in here!?!

Even if we abandon our simplistic view, the compiler must eventually generate some type of address for the CALL instruction. It cannot always assume that the writeln procedure comes immediately after the program.

Consider:

 import local.units.sdsu.io.*;

import java.lang.*;
double y;
public class LessSimple
{
public static void main(
String argv[]) throws IOException
{
y = Math.sin(2.0);

Format.print(System.out,"HELLO WORLD\n");
}
}

 
mem.eps

Figure 2.

It is obvious that the start address of 2nd print is going to be different. Therefore how could the compiler know what address to put in to the CALL instruction, so that all the address's for Figure 1 are known?

The compiler doesn't know (nor care) what address to put in the CALL INSTRUCTION. The compiler generates code (and information) which directs the LINK or ld program to "Fix-up" the address's once they become known. Compiler generates a symbolic address which tells the linker to do the fixup.


Thus when you execute program compiler puts
in symbolic addresses for pre-defined
functions/procedures and the linker program takes
this .o or .REL file.
It is called .REL because it is relocatable
code, i.e. it can be put in more than one
place in memory just as the print code was
moved to fit the sin code in memory.

The linker then determines what symbolic addresses need satisfying and then searches for these routines from a library of routines. Therefore it adds the code to the end of your program. It now has all addresses and can "fixup" CALL's. Therefore NOW program can run.

Look more closely at


Format.print(System.out,"HELLO WORLD\n");
How does print know that the argument passed is a literal string containing characters. Our code was
STOre string (or address) on stack CALL print

/* We may want to store address rather than object if it is very large. */

If all the print procedure gets is a value (or an address) it cannot tell if it is a string or an integer ( 5 characters in a word still is only binary and is an integer. There is nothing special about characters. )

The Java compiler generates information concerning:


(1) Type of the object (integer, real, logical)
(2) Kind of object (array, procedure, function)
(3) Run time address of object = symbolic
(4) Accessing Information: array - dimension - array bounds
procedure - list of parameters and their descriptions.
TABLE 2