Chapter 9: TRAP Routines and Subroutines

"Introduction to Computer Systems" review note

TRAP Routines

TRAP routines are a piece of code provided by the operating system. The user program can use a TRAP instruction to request the operating system to run a TRAP routine. TRAP routines are also known as service calls and system calls.

Why TRAP Routines?

  • It saves the work of application programmers (user programmers).
  • It is used to operate stuff which requires high privilege. For example, accessing I/O device registers may require high privilege, because if a user application does it wrong, it will create havoc for other programs. Therefore, only TRAP routines have the privilege to access I/O deviced registers. User programs can simply execute TRAP instructions to perform I/O tasks.

The TRAP Mechanism

The TRAP mechanism involves:

1. A Set of Service Routines

These service routines are part of the operating system and start at arbitrary addresses in memory.

2. The Trap Vector Table

The Trap Vector Table stores the starting address of each service routine. In LC-3, the Trap Vector Table is stored in memory locations x0000 to x00FF. Due to the size of the Trap Vector Table, LC-3 supports up to 256 service routines.

3. The TRAP instruction

In order for a service routine to execute, the user program must run the TRAP instruction.

In LC-3, the TRAP instruction provices the 8-bit trap vector. During the Execute phase of the TRAP instruction’s instruction cycle, the following things are done:

  • The 8-bit trap vector is zero-extended to a 16-bit address. It indicates an entry in the Trap Vector Table stored between x0000 and x00FF.
  • The 16-bit address is loaded into MAR.
  • The contents of the entry in the Trap Vector Table is read and loaded into MDR.
  • R7 is loaded with the current contents of the PC, which provides a linkage back to the user program before the TRAP routine finishes.
  • The contents of the MDR are loaded into the PC.

4. A Linkage Back to the User Program

At the end of each service routine, there must be a mechanism for returning control to the user program. This is done by the instruction JMP R7 (RET), since R7 stores the contents of the PC before the TRAP routine is executed.

Saving and Restoring Registers

When writing or using a TRAP routine or a subroutine, if a value in a register will be needed after a subsequent action which causes something else to be stored in that register, we must save it before that subsequent action and restore it for use after that subsequent action.

The save/restore problem can be handled either by the calling program (caller-save) or by the called program (callee-save). The appropriate one to handle the problem is the one that knows which registers will be destroyed by the subsequent actions.

An Example: The Character Output Service Routine

          .ORIG x0430
          ST    R1, SaveR1    ; This is the callee-save. R1 will be used
                              ; momentarily to poll the DSR hardware
; Write the character
TryWrite  LDI   R1, DSR
          BRzp  TryWrite
WriteIt   STI   R0, DDR       ; Write character

; Return from TRAP
Return    LD    R1, SaveR1    ; Restore R1
          RET                 ; Identical to "JMP R7"

; Constants
DSR       .FILL xFE04
DDR       .FILL xFE06
SaveR1    .BLKW #1
          .END

Note that the R1 is callee-saved, because the callee knows it will be destroyed. Similarly, the user program that invokes this TRAP routine should caller-save R0 and R7 if their contents will be used later.

Subroutines

Why Subroutines?

  • It can be invoked repetitively.
  • Collections of subroutines, called libraries, can be provided to programmers to free them from writing their own.

TRAP Routines and Subroutines

Similarities:

  • The Call-Return mechanism is similar. Both need an instruction to load the starting address of the called program to the PC, and a linkage (JMP R7 / RET) back to the user program.

Difference:

  • TRAP routines involve operating system resources, and they generally require privileged access to the underlying hardware of the computer.
  • Subroutines are written by the same person, a colleague, or provided as part of a library. They are not privileged.

The JSR(R) Instruction to Call Subroutines

JSR(R) instructions are used to call subroutines. Bit 11 of the instruction specifies the addressing mode, the value 1 if the addressing mode is PC-relative (the last 11 bits are the PCoffset), and the value 0 if the addressing mode is Base addressing (bits 8-6 are the base register).

An example:

; Main program
          ...
          JSR   WriteChar
          ...
; Subroutine WriteChar: display the character stored in R2
WriteChar LDI   R3, DSR
          BRzp  WriteChar
          STI   R2, DDR
          RET
DSR       .FILL xFE04
DDR       .FILL xFE06

Library Functions and the .EXTERNAL Pseudo-op

The library function and the user program are usually not assembled together (they are in different modules). They will be assembled separately, and will be combined when the executable image is produced (“at link time”). Therefore, when we assemble the user program, we will need the .EXTERNAL pseudo-op to tell the assembler that the label for the library function is in another module, so the assembler will leave it to the linker to deal with the label.

An example:

        ...
        .EXTERNAL SQRT ; Tells assembler the label is in another module
        ...
        LD    R4, BASE
        JSRR  R4       ; JSR is more often used to call library functions
;
BASE    .FILL SQRT     ; Value determined at link time
;
; The definition of SQRT is in another separately assembled module

类别:

标签:

发布于

留下评论

注意 评论系统在中国大陆加载不稳定。

回到顶部 ↑