📄 vaxashp.s
字号:
# of the recognized access violations. # # output parameters (exit via jmp instruction): # # if the exception is recognized (that is, if the exception pc is # associated with one of the mark points), control is passed to the # context-specific routine that restores the instruction state to # its initial state. # # these are the register values and stack state when the context # specific code begins execution. # # r0 - value of sp when exception occurred # r1 - scratch # r2 - scratch # r3 - scratch # r10 - scratch # # r0 -> zz(sp) - instruction-specific data begins here # # implicit output: # # the context-specific code accomplishes essentially the same thing for # all of the emulated instructions. # # the register contents are restored to the values that they had on # entry to the vax$xxxxxx routine. this causes the instruction to be # backed up almost (but not quite) to its starting point. (the operand # evaluation is not lost. the operands are saved in registers.) any # registers saved on entry are restored. # # output parameters (exit via rsb instruction): # # if the exception pc occurred somewhere else (such as a stack access), # the saved registers are restored and control is passed back to the # host system with an rsb instruction. # #-ashp_accvio: clrl r2 # initialize the counter pushab module_base # store base address of this module pushab module_end # store module end address jsb decimal$bounds_check # check if pc is inside the module addl2 $4,sp # discard end address subl2 (sp)+,r1 # get pc relative to this base1: cmpw r1,pc_table_base[r2] # is this the right pc? beql 3f # exit loop if true aoblss $table_size,r2,1b # do the entire table # if we drop through the dispatching based on pc, then the exception is not # one that we want to back up. we simply reflect the exception to the user.2: # popr #^m<r0,r1,r2,r3> # restore saved registers popr $0x0f rsb # return to exception dispatcher # the exception pc matched one of the entries in our pc table. r2 contains # the index into both the pc table and the handler table. r1 has served # its purpose and can be used as a scratch register.3: movzwl handler_table_base[r2],r1 # get the offset to the handler jmp module_base[r1] # pass control to the handler # in all of the instruction-specific routines, the state of the stack # will be shown as it was when the exception occurred. all offsets will # be pictured relative to r0. #+ # functional decsription: # # this routine is called by the exception handlers for the various # decimal string instruction emulation routines to perform a bounds # check on the exception pc. the real reason for performing this check # is that certain exceptions can occur in subroutines that are outside a # given module. in this case, it is not the exception pc but rather the # return pc on the top of the stack that determines the context of the # exception (and therefore, the code necessary to back up the # instruction state). # # the basic mode of operation is that, if the exception pc is outside # the current module boundarise, then r1 (the exception pc) is replaced # by the return pc (presumed pointed to by r0). # # input parameters: # # r0 - top of stack when exception occurred # r1 - pc at time of exception # # (r0) - return pc from subroutine in which access violation occurred # # 00(sp) - return pc from caller of this routine # 04(sp) - end address of module # 08(sp) - start address of module # # output parameters: # # if the exception pc is outside the bounds of the module (as defined by # the two longwords on the stack, then r1 is replaced by the "return # pc", the contents of the longword located by r0. # # if the exception pc is inside the module, nothing is changed by the # execution of this module. # # assumptions: # # there are two assumptions that must hold for these subroutines # in which access violations can occur. # # they must not use the stack. this keeps the return pc on the # top of the stack, located by r0. # # they must be called with a bsbw instruction. this causes the # return pc to be exactly three bytes beyond instruction that # transferred control to the subroutine. #- .globl decimal$bounds_checkdecimal$bounds_check: cmpl r1,4(sp) # beyond upper end? bgequ 1f # branch if out of bounds cmpl r1,8(sp) # within lower limit? blssu 1f # branch if out of bounds rsb # return with r1 intact # r1 is out of bounds. replace it with the return pc from the routine that # was executing when the access violation occurred. note that the pc is # backed up over the jsb instruction because the pc offset that appears in # the pc_table will be the pc of the jsb instruction and not the pc of the # next instruction. 1: subl3 $6,(r0),r1 # get new "exception" pc rsb #+ # functional description: # # the only difference among the various entry points is the number of # longwords on the stack. r0 is advanced beyond these longwords to point # to the list of saved registers. these registers are then restored, # effectively backing the routine up to its initial state. # # input parameters: # # r0 - address of top of stack when access violation occurred # # see specific entry points for details # # output parameters: # # see input parameter list for vax$decimal_accvio #- #+ # ashp_bsbw_20 # # an access violation occurred in subroutine strip_zeros or in subroutine # ashp_copy_source while the source string was being copied to the work space # on the stack. in addition to the five longwords of work space on the stack, # this routine has an additional longword, the return pc, on the stack. # # 00(r0) - return pc in mainline of vax$ashp # 04(r0) - first longword of scratch space # etc. #-ashp_bsbw_20: addl2 $4,r0 # skip over return pc and drop into ... #+ # ashp_20 # # there are five longwords of workspace on the stack for this entry point. # # 00(r0) - first longword of scratch space # . # . # 16(r0) - fifth longword of scratch space # 20(sp) - saved r0 # 24(sp) - saved r1 # etc. #-ashp_20: addl2 $20,r0 # discard scratch space on stack jmp vax$decimal_accvio # join common code to restore registers #+ # ashp_bsbw_8 # # an access violation occurred in subroutine add_packed_byte while the round # operand was being propogated. in addition to the saved r2/r3 pair of # longwords on the stack, this routine has an additional longword, the return # pc, on the stack. # # 00(r0) - return pc in mainline of vax$ashp # 04(r0) - saved intermediate value of r2 # etc. #-ashp_bsbw_8: addl2 $4,r0 # skip over return pc and drop into ... #+ # ashp_8 # # there is a saved register pair (two longwords) on the stack for these entry # points. # # 00(r0) - saved intermediate value of r2 # 04(r0) - saved intermediate value of r3 # 08(sp) - saved r0 # 12(sp) - saved r1 # 16(sp) - saved r2 # 20(sp) - saved r3 # etc. #-ashp_8: addl2 $8,r0 # discard saved register pair # drop into vax$decimal_accvio to restore saved registers #+ # ashp_0 # # the stack is empty. this label is merely a synonym for vax$decimal_accvio # because there is no context-specific work to do. # # 00(sp) - saved r0 # 04(sp) - saved r1 # 08(sp) - saved r2 # 12(sp) - saved r3 # etc. #-ashp_0: # drop into vax$decimal_accvio to restore saved registers #+ # functional description: # # this code is the final access violation processing for those # exceptions that have two things in common. # # the instruction/routine is to be backed up to its initial state. # # all registers from r0 to r11 were saved on entry to vax$xxxxxx. # # input parameters: # # 00(r0) - saved r0 on entry to vax$xxxxxx # 04(r0) - saved r1 # . # . # 44(r0) - saved r11 on entry to vax$xxxxxx # 48(r0) - return pc from vax$xxxxxx routine # # 00(sp) - saved r0 (restored by vax$handler) # 04(sp) - saved r1 # 08(sp) - saved r2 # 12(sp) - saved r3 # # output parameters: # # r0 is advanced over saved register array as the registers are restored. # r0 ends up pointing at the return pc. # # r1 contains the value of delta pc for all of the routines that # use this common code path. the fpd and accvio bits are both set # in r1. # # 00(r0) - return pc from vax$xxxxxx routine # # 00(sp) - value of r0 on entry to vax$xxxxxx # 04(sp) - value of r1 on entry to vax$xxxxxx # 08(sp) - value of r2 on entry to vax$xxxxxx # 12(sp) - value of r3 on entry to vax$xxxxxx # # r4 through r11 are restored to their values on entry to vax$xxxxxx. #- .globl vax$decimal_accviovax$decimal_accvio: movq (r0)+,pack_l_saved_r0(sp) # "restore" r0 and r1 movq (r0)+,pack_l_saved_r2(sp) # "restore" r2 and r3 movq (r0)+,r4 # really restore r4 and r5 movq (r0)+,r6 # ... and r6 and r7 movq (r0)+,r8 # ... and r8 and r8 movq (r0)+,r10 # ... and r10 and r11 # movl #<ashp_b_delta_pc!- # indicate offset for delta pc # pack_m_fpd!- # fpd bit should be set # pack_m_accvio>,r1 # this is an access violation movl $( ashp_b_delta_pc | pack_m_fpd | pack_m_accvio ),r1 jmp vax$reflect_fault # continue exception handling # end_mark_pointmodule_end:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -