376 lines
		
	
	
	
		
			14 KiB
		
	
	
	
		
			Text
		
	
	
	
	
	
			
		
		
	
	
			376 lines
		
	
	
	
		
			14 KiB
		
	
	
	
		
			Text
		
	
	
	
	
	
.SN 8
 | 
						|
.VS 1 0
 | 
						|
.BP
 | 
						|
.S1 "ENVIRONMENT INTERACTIONS"
 | 
						|
EM programs can interact with their environment in three ways.
 | 
						|
Two, starting/stopping and monitor calls, are dealt with in this chapter.
 | 
						|
The remaining way to interact, interrupts, will be treated
 | 
						|
together with traps in chapter 9.
 | 
						|
.S2 "Program starting and stopping"
 | 
						|
EM user programs start with a call to a procedure called
 | 
						|
m_a_i_n.
 | 
						|
The assembler and backends look for the definition of a procedure
 | 
						|
with this name in their input.
 | 
						|
The call passes three parameters to the procedure.
 | 
						|
The parameters are similar to the parameters supplied by the
 | 
						|
UNIX
 | 
						|
.FS
 | 
						|
UNIX is a Trademark of Bell Laboratories.
 | 
						|
.FE
 | 
						|
operating system to C programs.
 | 
						|
These parameters are often called
 | 
						|
.BW argc ,
 | 
						|
.B argv
 | 
						|
and
 | 
						|
.BW envp .
 | 
						|
Argc is the parameter nearest to LB and is a wordsized integer.
 | 
						|
The other two are pointers to the first element of an array of
 | 
						|
string pointers.
 | 
						|
.N
 | 
						|
The
 | 
						|
.B argv
 | 
						|
array contains
 | 
						|
.B argc
 | 
						|
strings, the first of which contains the program call name.
 | 
						|
The other strings in the
 | 
						|
.B argv
 | 
						|
array are the program parameters.
 | 
						|
.P
 | 
						|
The
 | 
						|
.B envp
 | 
						|
array contains strings in the form "name=string", where 'name'
 | 
						|
is the name of an environment variable and string its value.
 | 
						|
The
 | 
						|
.B envp
 | 
						|
is terminated by a zero pointer.
 | 
						|
.P
 | 
						|
An EM user program stops if the program returns from the first
 | 
						|
invocation of m_a_i_n.
 | 
						|
The contents of the function return area are used to procure a
 | 
						|
wordsized program return code.
 | 
						|
EM programs also stop when traps and interrupts occur that are
 | 
						|
not caught and when the exit monitor call is executed.
 | 
						|
.S2 "Input/Output and other monitor calls"
 | 
						|
EM differs from most conventional machines in that it has high level i/o
 | 
						|
instructions.
 | 
						|
Typical instructions are OPEN FILE and READ FROM FILE instead
 | 
						|
of low level instructions such as setting and clearing
 | 
						|
bits in device registers.
 | 
						|
By providing such high level i/o primitives, the task of implementing
 | 
						|
EM on various non EM machines is made considerably easier.
 | 
						|
.P
 | 
						|
I/O is initiated by the MON instruction, which expects an iocode on top
 | 
						|
of the stack.
 | 
						|
Often there are also parameters which are pushed on the
 | 
						|
stack in reverse order, that is: last
 | 
						|
parameter first.
 | 
						|
Some i/o functions also provide results, which are returned on the stack.
 | 
						|
In the list of monitor calls we use several types of parameters and results,
 | 
						|
these types consist of integers and unsigneds of varying sizes, but never
 | 
						|
smaller than the wordsize, and the two pointer types.
 | 
						|
.N 1
 | 
						|
The names of the types used are:
 | 
						|
.IS 4
 | 
						|
.PS - 10
 | 
						|
.PT int
 | 
						|
an integer of wordsize
 | 
						|
.PT int2
 | 
						|
an integer whose size is the maximum of the wordsize and 2
 | 
						|
bytes
 | 
						|
.PT int4
 | 
						|
an integer whose size is the maximum of the wordsize and 4
 | 
						|
bytes
 | 
						|
.PT intp
 | 
						|
an integer with the size of a pointer
 | 
						|
.PT uns2
 | 
						|
an unsigned integer whose size is the maximum of the wordsize and 2
 | 
						|
.PT unsp
 | 
						|
an unsigned integer with the size of a pointer
 | 
						|
.PT ptr
 | 
						|
a pointer into data space
 | 
						|
.PE 1
 | 
						|
.IE 0
 | 
						|
The table below lists the i/o codes with their results and
 | 
						|
parameters.
 | 
						|
This list is similar to the system calls of the UNIX Version 7
 | 
						|
operating system.
 | 
						|
.BP
 | 
						|
.A
 | 
						|
To execute a monitor call, proceed as follows:
 | 
						|
.IS 2
 | 
						|
.N 1
 | 
						|
.PS a 4 "" )
 | 
						|
.PT
 | 
						|
Stack the parameters, in reverse order, last parameter first.
 | 
						|
.PT
 | 
						|
Push the monitor call number (iocode) onto the stack.
 | 
						|
.PT
 | 
						|
Execute the MON instruction.
 | 
						|
.PE 1
 | 
						|
.IE
 | 
						|
An error code is present on the top of the stack after
 | 
						|
execution of most monitor calls.
 | 
						|
If this error code is zero, the call performed the action
 | 
						|
requested and the results are available on top of the stack.
 | 
						|
Non-zero error codes indicate a failure, in this case no
 | 
						|
results are available and the error code has been pushed twice.
 | 
						|
This construction enables programs to test for failure with a
 | 
						|
single instruction (~TEQ or TNE~) and still find out the cause of
 | 
						|
the failure.
 | 
						|
The result name 'e' is reserved for the error code.
 | 
						|
.N 1
 | 
						|
List of monitor calls.
 | 
						|
.DS B
 | 
						|
number name    parameters      results           function
 | 
						|
 | 
						|
   1   Exit    status:int                        Terminate this process
 | 
						|
   2   Fork                    e,flag,pid:int    Spawn new process
 | 
						|
   3   Read    fildes:int;buf:ptr;nbytes:unsp
 | 
						|
                               e:int;rbytes:unsp Read from file
 | 
						|
   4   Write   fildes:int;buf:ptr;nbytes:unsp
 | 
						|
                               e:int;wbytes:unsp Write on a file
 | 
						|
   5   Open    string:ptr;flag:int
 | 
						|
                               e,fildes:int      Open file for read and/or write
 | 
						|
   6   Close   fildes:int      e:int             Close a file
 | 
						|
   7   Wait                    e:int;status,pid:int2
 | 
						|
                                                 Wait for child
 | 
						|
   8   Creat   string:ptr;mode:int
 | 
						|
                               e,fildes:int      Create a new file
 | 
						|
   9   Link    string1,string2:ptr
 | 
						|
                               e:int             Link to a file
 | 
						|
  10   Unlink  string:ptr      e:int             Remove directory entry
 | 
						|
  12   Chdir   string:ptr      e:int             Change default directory
 | 
						|
  14   Mknod   string:ptr;mode,addr:int2
 | 
						|
                               e:int             Make a special file
 | 
						|
  15   Chmod   string:ptr;mode:int2
 | 
						|
                               e:int             Change mode of file
 | 
						|
  16   Chown   string:ptr;owner,group:int2
 | 
						|
                               e:int             Change owner/group of a file
 | 
						|
  18   Stat    string,statbuf:ptr
 | 
						|
                               e:int             Get file status
 | 
						|
  19   Lseek   fildes:int;off:int4;whence:int
 | 
						|
                               e:int;oldoff:int4 Move read/write pointer
 | 
						|
  20   Getpid                  pid:int2          Get process identification
 | 
						|
  21   Mount   special,string:ptr;rwflag:int
 | 
						|
                               e:int             Mount file system
 | 
						|
  22   Umount  special:ptr     e:int             Unmount file system
 | 
						|
  23   Setuid  userid:int2     e:int             Set user ID
 | 
						|
  24   Getuid                  e_uid,r_uid:int2  Get user ID
 | 
						|
  25   Stime   time:int4       e:int             Set time and date
 | 
						|
  26   Ptrace  request:int;pid:int2;addr:ptr;data:int
 | 
						|
                               e,value:int       Process trace
 | 
						|
  27   Alarm   seconds:uns2    previous:uns2     Schedule signal
 | 
						|
  28   Fstat   fildes:int;statbuf:ptr
 | 
						|
                               e:int             Get file status
 | 
						|
  29   Pause                                     Stop until signal
 | 
						|
  30   Utime   string,timep:ptr
 | 
						|
                               e:int             Set file times
 | 
						|
  33   Access  string,mode:int e:int             Determine file accessibility
 | 
						|
  34   Nice    incr:int                          Set program priority
 | 
						|
  35   Ftime   bufp:ptr        e:int             Get date and time
 | 
						|
  36   Sync                                      Update filesystem
 | 
						|
  37   Kill    pid:int2;sig:int
 | 
						|
                               e:int             Send signal to a process
 | 
						|
  41   Dup     fildes,newfildes:int
 | 
						|
                               e,fildes:int      Duplicate a file descriptor
 | 
						|
  42   Pipe                    e,w_des,r_des:int Create a pipe
 | 
						|
  43   Times   buffer:ptr                        Get process times
 | 
						|
  44   Profil  buff:ptr;bufsiz,offset,scale:intp Execution time profile
 | 
						|
  46   Setgid  gid:int2        e:int             Set group ID
 | 
						|
  47   Getgid                  e_gid,r_gid:int   Get group ID
 | 
						|
  48   Sigtrp  trapno,signo:int
 | 
						|
                               e,prevtrap:int    See below
 | 
						|
  51   Acct    file:ptr        e:int             Turn accounting on or off
 | 
						|
  53   Lock    flag:int        e:int             Lock a process
 | 
						|
  54   Ioctl   fildes,request:int;argp:ptr
 | 
						|
                               e:int             Control device
 | 
						|
  56   Mpxcall cmd:int;vec:ptr e:int             Multiplexed file handling
 | 
						|
  59   Exece   name,argv,envp:ptr
 | 
						|
                               e:int             Execute a file
 | 
						|
  60   Umask   complmode:int2  oldmask:int2      Set file creation mode mask
 | 
						|
  61   Chroot  string:ptr      e:int             Change root directory
 | 
						|
.DE 1
 | 
						|
Codes 0, 11, 13, 17, 31, 32, 38, 39, 40, 45, 49, 50, 52,
 | 
						|
55, 57, 58, 62, and 63 are
 | 
						|
not used.
 | 
						|
.P
 | 
						|
All monitor calls, except fork and sigtrp
 | 
						|
are the same as the UNIX version 7 system calls.
 | 
						|
.P
 | 
						|
The sigtrp entry maps UNIX signals onto EM interrupts.
 | 
						|
Normally, trapno is in the range 0 to 252.
 | 
						|
In that case it requests that signal signo
 | 
						|
will cause trap trapno to occur.
 | 
						|
When given trap number -2, default signal handling is reset, and when given
 | 
						|
trap number -3, the signal is ignored.
 | 
						|
.P
 | 
						|
The flag returned by fork is 1 in the child process and 0 in
 | 
						|
the parent.
 | 
						|
The pid returned is the process-id of the other process.
 | 
						|
.BP
 | 
						|
.S1 "TRAPS AND INTERRUPTS"
 | 
						|
EM provides a means for the user program to catch all traps
 | 
						|
generated by the program itself, the hardware, or external conditions.
 | 
						|
This mechanism uses five instructions: LIM, SIM, SIG, TRP and RTT.
 | 
						|
This section of the manual may be omitted on the first reading since it
 | 
						|
presupposes knowledge of the EM instruction set.
 | 
						|
.P
 | 
						|
The action taken when a trap occures is determined by the value
 | 
						|
of an internal EM trap register.
 | 
						|
This register contains a pointer to a procedure.
 | 
						|
Initially the pointer used is zero and all traps halt the
 | 
						|
program with, hopefully, a useful message to the outside world.
 | 
						|
The SIG instruction can be used to alter the trap register,
 | 
						|
it pops a procedure pointer from the
 | 
						|
stack into the trap register.
 | 
						|
When a trap occurs after storing a nonzero value in the trap
 | 
						|
register, the procedure pointed to by the trap register
 | 
						|
is called with the trap number
 | 
						|
as the only parameter (see below).
 | 
						|
SIG returns the previous value of the trap register on the
 | 
						|
stack.
 | 
						|
Two consecutive SIGs are a no-op.
 | 
						|
When a trap occurs, the trap register is reset to its initial
 | 
						|
condition, to prevent recursive traps from hanging the machine up,
 | 
						|
e.g. stack overflow in the stack overflow handling procedure.
 | 
						|
.P
 | 
						|
The runtime systems for some languages need to ignore some EM
 | 
						|
traps.
 | 
						|
EM offers a feature called the ignore mask.
 | 
						|
It contains one bit for each of the lowest 16 trap numbers.
 | 
						|
The bits are numbered 0 to 15, with the least significant bit
 | 
						|
having number 0.
 | 
						|
If a certain bit is 1 the corresponding trap never
 | 
						|
occurs and processing simply continues.
 | 
						|
The actions performed by the offending instruction are
 | 
						|
described by the Pascal program in appendix A.
 | 
						|
.N
 | 
						|
If the bit is 0, traps are not ignored.
 | 
						|
The instructions LIM and SIM allow copying and replacement of
 | 
						|
the ignore mask.~
 | 
						|
.P
 | 
						|
The TRP instruction generates a trap, the trap number being found on the
 | 
						|
stack.
 | 
						|
This is, among other things,
 | 
						|
useful for library procedures and runtime systems.
 | 
						|
It can also be used by a low level trap procedure to pass the trap to a
 | 
						|
higher level one (see example below).
 | 
						|
.P
 | 
						|
The RTT instruction returns from the trap procedure and continues after the
 | 
						|
trap.
 | 
						|
In the list below all traps marked with an asterisk ('*') are
 | 
						|
considered to be fatal and it is explicitly undefined what happens if
 | 
						|
you try to restart after the trap.
 | 
						|
.P
 | 
						|
The way a trap procedure is called is completely compatible
 | 
						|
with normal calling conventions. The only way a trap procedure
 | 
						|
differs from normal procedures is the return. It has to use RTT instead
 | 
						|
of RET. This is necessary because the complete runtime status is saved on the
 | 
						|
stack before calling the procedure and all this status has to be reloaded.
 | 
						|
Error numbers are in the range 0 to 252.
 | 
						|
The trap numbers are divided into three categories:
 | 
						|
.IS 4
 | 
						|
.N 1
 | 
						|
.PS - 10
 | 
						|
.PT ~~0-~63
 | 
						|
EM machine errors, e.g. illegal instruction.
 | 
						|
.PS - 8
 | 
						|
.PT ~0-15
 | 
						|
maskable
 | 
						|
.PT 16-63
 | 
						|
not maskable
 | 
						|
.PE
 | 
						|
.PT ~64-127
 | 
						|
Reserved for use by compilers, run time systems, etc.
 | 
						|
.PT 128-252
 | 
						|
Available for user programs.
 | 
						|
.PE 1
 | 
						|
.IE
 | 
						|
EM machine errors are numbered as follows:
 | 
						|
.DS I 5
 | 
						|
.TS
 | 
						|
tab(@);
 | 
						|
n l l.
 | 
						|
0@EARRAY@Array bound error
 | 
						|
1@ERANGE@Range bound error
 | 
						|
2@ESET@Set bound error
 | 
						|
3@EIOVFL@Integer overflow
 | 
						|
4@EFOVFL@Floating overflow
 | 
						|
5@EFUNFL@Floating underflow
 | 
						|
6@EIDIVZ@Divide by 0
 | 
						|
7@EFDIVZ@Divide by 0.0
 | 
						|
8@EIUND@Undefined integer
 | 
						|
9@EFUND@Undefined float
 | 
						|
10@ECONV@Conversion error
 | 
						|
16*@ESTACK@Stack overflow
 | 
						|
17*@EHEAP@Heap overflow
 | 
						|
18*@EILLINS@Illegal instruction
 | 
						|
19*@EODDZ@Illegal size argument
 | 
						|
20*@ECASE@Case error
 | 
						|
21*@EMEMFLT@Addressing non existent memory
 | 
						|
22*@EBADPTR@Bad pointer used
 | 
						|
23*@EBADPC@Program counter out of range
 | 
						|
24@EBADLAE@Bad argument of LAE
 | 
						|
25@EBADMON@Bad monitor call
 | 
						|
26@EBADLIN@Argument of LIN too high
 | 
						|
27@EBADGTO@GTO descriptor error
 | 
						|
.TE
 | 
						|
.DE 0
 | 
						|
.P
 | 
						|
As an example,
 | 
						|
suppose a subprocedure has to be written to do a numeric
 | 
						|
calculation.
 | 
						|
When an overflow occurs the computation has to be stopped and
 | 
						|
the higher level procedure must be resumed.
 | 
						|
This can be programmed as follows using the mechanism described above:
 | 
						|
.DS B
 | 
						|
 mes 2,2,2              ; set sizes
 | 
						|
ersave
 | 
						|
 bss 2,0,0              ; Room to save previous value of trap procedure
 | 
						|
msave
 | 
						|
 bss 2,0,0              ; Room to save previous value of trap mask
 | 
						|
 | 
						|
 pro calcule,0          ; entry point
 | 
						|
 lxl 0                  ; fill in non-local goto descriptor with LB
 | 
						|
 ste jmpbuf+4
 | 
						|
 lor 1                  ; and SP
 | 
						|
 ste jmpbuf+2
 | 
						|
 lim                    ; get current ignore mask
 | 
						|
 ste msave              ; save it
 | 
						|
 lim
 | 
						|
 loc 4                  ; bit for EFOVFL
 | 
						|
 ior 2                  ; set in mask
 | 
						|
 sim                    ; ignore EFOVFL from now on
 | 
						|
 lpi $catch             ; load procedure identifier
 | 
						|
 sig                    ; catch wil get all traps now
 | 
						|
 ste ersave             ; save previous trap procedure identifier
 | 
						|
; perform calculation now, possibly generating overflow
 | 
						|
1                       ; label jumped to by catch procedure
 | 
						|
 loe ersave             ; get old trap procedure
 | 
						|
 sig                    ; refer all following trap to old procedure
 | 
						|
 asp 2                  ; remove result of sig
 | 
						|
 loe msave              ; restore previous mask
 | 
						|
 sim                    ; done now
 | 
						|
; load result of calculation
 | 
						|
 ret 2                  ; return result
 | 
						|
jmpbuf
 | 
						|
 con *1,0,0
 | 
						|
 end
 | 
						|
.DE 0
 | 
						|
.VS 1 1
 | 
						|
.DS
 | 
						|
Example of catch procedure
 | 
						|
 pro catch,0            ; Local procedure that must catch the overflow trap
 | 
						|
 lol 2                  ; Load trap number
 | 
						|
 loc 4                  ; check for overflow
 | 
						|
 bne *1                 ; if other trap, call higher trap procedure
 | 
						|
 gto jmpbuf             ; return to procedure calcule
 | 
						|
1                       ; other trap has occurred
 | 
						|
 loe ersave             ; previous trap procedure
 | 
						|
 sig                    ; other procedure will get the traps now
 | 
						|
 asp 2                  ; remove the result of sig
 | 
						|
 lol 2                  ; stack trap number
 | 
						|
 trp                    ; call other trap procedure
 | 
						|
 rtt                    ; if other procedure returns, do the same
 | 
						|
 end
 | 
						|
.DE
 |