banner



Is It Ever Safe For A Mips User Program To Use Registers $k0 $k1

09. Exceptions and traps

What is «system event»?

  • Occurs while program running
  • Has a cause

    1. Interrupt: not mentioned by the program, caused by external source (device I/O, hardware malfunction etc.)

    2. Exception: the program supposes certain kind of event at certain code position (like zero division or overflow)

    3. Trap: the program initiates event itself (simulates event)

  • Requires processing: switching from normal execution flow to handler and back

    • (way to implement) Store $pc, then change in to predefined value (handler), and restore after processing

  • Can be asynchronous

    • ⇒ non-atomic corruption
    • ⇒ races

Event type

Code position

Sure

Source

Name

Unexpected situation during execution: zero division, illegal instruction, illegal address etc.

Fixed

No

Internal

exception

Simulation of unexpected situation: «nothing happens, but we want to call a handler»

Fixed

Yes

Internal

trap

Expected situation handled by operating system (calling a certain system subroutine outside program code)

Fixed

Yes

Internal

syscall

Device request (like status change, I/O operation result, timer etc.)

Random

No

External

interrupt

Fatal device malfunction (bad media, system failure etc.)

Sometimes predictable

No

External

interrupt

Implementation:

  • Interrupt vectors (not in MIPS). When interrupt № K occurs, CPU picks actual handler address from jump table (jump table is a common technology for tasks like this)

    • Address

      Content

      Meaning

      0x80000100

      0x80000180

      Interrupt № 0 handler address

      0x80000104

      0x800007ac

      Interrupt № 1 handler address

      0x80000108

      0x800015b0

      Interrupt № 2 handler address

      0x80000120

      0x80000e54

      Interrupt № 8 handler address

    • Interrupt vectors doubles memory access and requires additional addiu

    • In theory, requires double indirect addressing
  • Single handler (MIPS: kernel subroutine at 0x80000180)

    • Needs more direct calculations to distinguish types of events

Hardware requirements:

  • Inhibit or restrict recurrent events (injecting event while already in handler)

  • Set type of event in dedicated register
  • Store return address (esp. when handling interrupt)
  • (not in MIPS) upon entering handler, keep all registers (incl. flag register and other status ones), restore them before return
  • Fix microcode / pipeline / and all that

MIPS: exceptions

Exceptions, events and traps are handled by control CPU CPU0.

MARS: only partial support:

Name

Number

Purpose

BadVAddr

8

Address caused exception (if exception is related to incorrect memory addressing)

Status

12

Flags bit scale (interrupt mask, permissions etc.)

Cause

13

Event type and delayed event info

EPC

14

Address of instruction caused the exception or being executed when interrupt occurred

Instructions:

  1. mfc0 Rdest, C0src — move from C0 register C0src to common register Rdest

  2. mtc0 Rsrc C0des — move to C0

  3. eret — return from exception

Exception handling:

  1. Set up bit 1 of C0 $12 Status register (EXception Level, EXL).
  2. Set up bits 2-6 of C0 $13 Cause to exception type
  3. Store current instruction address to C0 $14 EPC
  4. If invalid addressing took place, set C0 $8 BadVAddr to accused memory address
  5. Jump to 0x8000180 (this address is fixed for MIPS32). The .ktext section (kernel code) is started from 0x8000000, so on real MIPS some instructions can be executed only from that part of memory.

  6. Handler must call eret after processing. This jumps to address stored at $14 (EPC) and cleans EXL status bit in $12.

    • When handling exception it's good idea to add 4 to EPC, so exception won't occur again

Real MIPS hardware and accurate simulators always have something in kernel space, but MARS has nothing and handles all exceptions/syscalls by executing Java code.

The Status C0 register (slightly MARS-specific):

bits

31-16

15-8

7-5

4

3-2

1

0

target

unused

Int. mask

unused

K/U

unused

Exception level

Int enable

  • Interrupt mask — bit scale of enabled/disabled (1/0) interrupts. Disabled interrupts are ignored
  • Kernel Mode / User Mode — indicating whether CPU in kernel or user mode (MARS: always kernel)
  • Exception level — is set to 1 while handling exception, disables recurrence
  • Interrupt enable — global interrupt handling enable/disable (1/0)

The Cause C0 register

bits

31

30-16

15-8

7

6-2

1-0

target

Br

unused

Pending interrupts

unused

Exception code

unused

  • Br: 1 if
  • Pending interrupts: bit scale of interrupts just occurred. Being asynchronous, interrupts can occur simultaneously

  • Exception code is set to the exception type

Exception handler

Exception types (partially in MARS):

  • ADDRESS_EXCEPTION_LOAD (4)
  • ADDRESS_EXCEPTION_STORE (5)
  • SYSCALL_EXCEPTION (8) (MARS : exception while handling syscall)),

  • BREAKPOINT_EXCEPTION (9) (MARSsimulate DIVIDE_BY_ZERO_EXCEPTION),

  • RESERVED_INSTRUCTION_EXCEPTION (10),
  • ARITHMETIC_OVERFLOW_EXCEPTION (12),
  • TRAP_EXCEPTION ( 13),
  • DIVIDE_BY_ZERO_EXCEPTION (15) (not in MARS),
  • FLOATING_POINT_OVERFLOW (16),
  • FLOATING_POINT_UNDERFLOW (17).

Registers: handler can use $k0 and $k1 registers only, and must keep all other registers intact. Nothing should be changed after eret.

  • It's common to use separate kernel stack, but there's no hardware support for it. There's no urgent need for stack, because exception handlers are non-recurrent

Simple example (debug it step by step):

                                          1                                                        .text                                                      2                                                        nop                                                      3                                                        lw              $              t0, ($              zero)      #              illegal              read              from              0x00000000                                                      4                                                        li              $              v0              10                                                      5                                                        syscall                                                      6                                                                                                7                                                        .ktext              0x80000180                                                      8                                                        mfc0              $              k0              $              14              #              EPC              keeps              address              of              accused              instruction                                                      9                                                        #              See              al              so              BadVAddr                                                      10                                                        addi              $              k0              $              k0,4              #              Next              instruction              is              at              EPC+4                                                      11                                                        mtc0              $              k0              $              14              #              Store              that              to              EPС                                          12                                                        eret              #              Continue              normal              execution                      

Our more thorough handler must keep all registers intact, except for $k0 and $k1.

                                          1                                                        .text                                                      2                                                        lui              $              t0              0x7fff                                                      3                                                        addi              $              t0              $              t0              0xffff                                                      4                                                        addi              $              t0              $              t0              0xffff              #              integer              overflow                                                      5                                                        sw              $              t0              0x400              #              bad              addressing                                                      6                                                        divu              $              t0              $              t0              $              zero              #              zero              di              vision                                                      7                                                        teq              $              zero              $              zero              #              trap              (exception              si              mulation)                                          8                                                        li              $              v0              10                                                      9                                                        syscall                                                      10                                                        .kdata                                                      11                                                        msg:              .asciiz              "Exception "                                                      12                                                        .ktext              0x80000180                                                      13                                                        move              $              k0              $              v0              #              keep              $              v0                                                      14                                                        move              $              k1              $              a0              #              keep              $              a0                                                      15                                                        la              $              a0              msg              #              print              a              message                                                      16                                                        li              $              v0              4                                                      17                                                        syscall                                                      18                                                        mfc0              $              a0              $              13              #              take              Cause                                                      19                                                        srl              $              a0              $              a0              2              #              shift              to              cause              number                                                      20                                                        andi              $              a0              $              a0              0x1f              #              separate              it              from              other              bits                                                      21                                                        li              $              v0              1              #              print              cause                                                      22                                                        syscall                                                      23                                                        li              $              a0              10                                                      24                                                        li              $              v0              11              #              print              '\n'                                                      25                                                        syscall                                                      26                                                                                                27                                                        move              $              v0              $              k0              #              restore              $              v0                                                      28                                                        move              $              a0              $              k1              #              restore              $              a0                                                      29                                                                                                30                                                        li              $              k0              0                                                      31                                                        mtc0              $              k0              $              13              #              cl              ean              Cause                                                      32                                                        mfc0              $              k0              $              14              #              take              current              instruction              address              from              EPC                                                      33                                                        addi              $              k0              $              k0,4              #              calculate              next              instruction              address                                                      34                                                        mtc0              $              k0              $              14              #              store              back              to              EPС                                          35                                                        eret              #              let              the              program              continue                      

Q: what common register we've corrupted anyway?

Note:

  • MARS break command and the corresponded exception are nothing to do with breakpoints. Breakpoints is operated «by hardware» — in MARS case by executing corresponded Java code.

    • IRL breakpoint exception is used by debuggers. The debuggers remembers the instruction to be breakpointed a writes break to it's place. And when break exception occures, deals it with the situation.

  • MARS has no «division by zero» exception and emulates it by break

MIPS: traps

MIPS system event handling is fast an furious, so programmer may want to take advantage of it, developing new exceptions manually.

Trap is exception 13 and handles like all exceptions.

teq $t1,$t2

Trap if equal

Trap if $t1 is equal to $t2

teqi $t1,-100

Trap if equal to immediate

Trap if $t1 is equal to sign-extended 16 bit immediate

tge $t1,$t2

Trap if greater or equal

Trap if $t1 is greater than or equal to $t2

tgei $t1,-100

Trap if greater than or equal to immediate

Trap if $t1 greater than or equal to sign-extended 16 bit immediate

tgeiu $t1,-100

Trap if greater or equal to immediate unsigned

Trap if $t1 greater than or equal to sign-extended 16 bit immediate, unsigned comparison

tgeu $t1,$t2

Trap if greater or equal unsigned

Trap if $t1 is greater than or equal to $t2 using unsigned comparision

tlt $t1,$t2

Trap if less than

Trap if $t1 less than $t2

tlti $t1,-100

Trap if less than immediate

Trap if $t1 less than sign-extended 16-bit immediate

tltiu $t1,-100

Trap if less than immediate unsigned

Trap if $t1 less than sign-extended 16-bit immediate, unsigned comparison

tltu $t1,$t2

Trap if less than unsigned

Trap if $t1 less than $t2, unsigned comparison

tne $t1,$t2

Trap if not equal

Trap if $t1 is not equal to $t2

tnei $t1,-100

Trap if not equal to immediate

Trap if $t1 is not equal to sign-extended 16 bit immediate

Note these are atomic operations!

When trap is emitted, exception handler detects type 13 (trap) and can perform different actions based on EPC value (we know every trap address for sure).

R-type trap instruction can bear additional information at third register parameter field (dst). Handler can extract this data by reading and parsing word with the instruction, taken from address stored in EPC. But MARS assembler has no such feature.

Where to use:

  • Assertion. If some unwanted/improbable situation evolves, do not deal with it, but pass to the higher level. To stop calculation is sometimes better than to continue it wit wrong data. This example illustrates infinite loop prevention by checking if increment is non-zero:
                                                          1                                                                        teqi                  $                  t1                  0                                                                      2                                                                        subu                  $                  t0                  $                  t0                  $                  t1                                                                      3                                                                        bgez                  $                  t0                  loop                              
  • Inject software exception in case there's no hardware one. This example traps on array bound violation:
                                                          1                                                                        .eqv                  SZ                  10                                                                      2                                                                        .data                                                                      3                                                                        array:                  .space                  SZ                                                                      4                                                                        bound:                  .align                  2                                                                      5                                                                                                                            6                                                                        .text                                                                      7                                                                        li                  $                  v0                  5                                                                      8                                                                        syscall                                                                      9                                                                        move                  $                  t0                  $                  v0                                                                      10                                                                        la                  $                  t1                  array                                                                      11                                                                        la                  $                  t2                  bound                                                                      12                                                                        loop:                  tge                  $                  t1                  $                  t2                                                                      13                                                                        sw                  $                  t0                  ($                  t1)                                                      14                                                                        addiu                  $                  t0                  $                  t0                  -1                                                                      15                                                                        addiu                  $                  t1                  $                  t1                  4                                                                      16                                                                        bgtz                  $                  t0                  loop                                                                      17                                                                                                                            18                                                                        li                  $                  v0                  10                                                                      19                                                                        syscall                              

H/W

  • EJudge: NoError 'No errors'

    Write a program that inputs 10 integers, not taking in account failed inputs. When all 10 integers are read, the program outputs them.

    Input:
                    zz                20                fwewefqwe                .654                71                -124                0.1                82                6.                334423                -94                VII                7535                6                .                -                17                8968
    Output:
                    20                71                -124                82                334423                -94                7535                6                17                8968
  • EJudge: NotOval 'Not Oval'

    Write a program that inputs two integers (paper color and ink color) and draws an oval on Mars «Bitmap Display» with following settings (note 4X4 pixel size:

    • egg.png

    To draw an oval you should scale a circle to fit screen rectangle. Look at the example code. After drawing an oval, the program prints all videomemory out in hexadecimal.

    Input: Output:
                    0x00338811                0x00338811                0x00338811                ...                0x00ffcc55                0x00ffcc55                0x00ffcc55                ...                0x00338811                0x00338811                0x00338811

HSE/ArchitectureASM/09_ExceptionsTraps (последним исправлял пользователь FrBrGeorge 2019-12-15 09:13:20)

Is It Ever Safe For A Mips User Program To Use Registers $k0 $k1

Source: http://uneex.ru/HSE/ArchitectureASM/09_ExceptionsTraps

Posted by: welchtunised.blogspot.com

0 Response to "Is It Ever Safe For A Mips User Program To Use Registers $k0 $k1"

Post a Comment

Iklan Atas Artikel

Iklan Tengah Artikel 1

Iklan Tengah Artikel 2

Iklan Bawah Artikel