📄 vaxstring.s
字号:
# the following instruction is the exit path when the destination string # has zero length on input.L40: movzwl r0,r0 # clear unused bits of srclen brb L30 # exit through common code # this code executes if the source string is at a smaller virtual address # than the destination string. the movement takes place from the back # (high address end) of each string to the front (low address end).move_backward: addl2 r4,r5 # point r5 one byte beyond destination subl2 r0,r4 # get amount of fill work to do bgtru L50 # branch to fill loop if work to do movzwl 8(sp),r0 # use dstlen (saved r4) as srclen (r0) brb L60 # skip loop that does fill characters # MARK_POINT MOVTC_4 .text 2 .set table_size, table_size + 1 .word Lmovtc_4 - module_base .text 3 .word movtc_4 - module_base .textLmovtc_4:L50: movb r2,-(r5) # load fill characters from the back sobgtr r4,L50 # continue until excess all doneL60: addl2 r0,r1 # point r1 to "modified end" of source # move transtaled characters from the high-address end toward the low-address # end. note that the fill character is no longer needed so that r2 is # available as a scratch register. # MARK_POINT MOVTC_5 .text 2 .set table_size, table_size + 1 .word Lmovtc_5 - module_base .text 3 .word movtc_5 - module_base .textLmovtc_5:L70: movzbl -(r1),r2 # get next character # MARK_POINT MOVTC_6 .text 2 .set table_size, table_size + 1 .word Lmovtc_6 - module_base .text 3 .word movtc_6 - module_base .textLmovtc_6: movb (r3)[r2],-(r5) # move translated character sobgtr r0,L70 # continue until source is exhausted # at this point, r1 points to the first character in the source string and r5 # points to the first character in the destination string. this is the result # of operating on the strings from back to front (high-address end to # low-address end). these registers must be modified to point to the ends of # their respective strings. this is accomplished by using the saved original # lengths of the two strings. note that at this stage of the routine, r2 is # no longer needed and so can be used as a scratch register. movzwl 6(sp),r2 # get original source length addl2 r2,r1 # point r1 to end of source string movzwl 10(sp),r2 # get original destination length addl2 r2,r5 # point r5 to end of destination string # if r1 is negative, this indicates that the source string is smaller than the # destination. r1 must be readjusted to point to the first byte that was not # translated. r0, which contains zero, must be loaded with the number of bytes # that were not translated (the negative of the contents of r4). tstl r4 # any more work to do? beql L30 # exit through common code addl2 r4,r1 # back up r1 (r4 is negative) # the exit code for move_forward also comes here is the source is longer than # (or equal to) the destination. note that in the case of r4 containing zero, # some extra work that accomplishes nothing must be done. this extra work in # the case of equal strings avoids two extra instructions in all cases.L80: mnegl r4,r0 # remaining source length to r0 clrl r4 # r4 is always zero on exit brb L30 # exit through common code #+ # functional description: # # the source string specified by the source length and source address # operands is translated and replaces the destination string specified by # the destination length and destination address operands. translation is # accomplished by using each byte of the source string as index into a 256 # byte table whose zeroth entry address is specified by the table address # operand. the byte selected replaces the byte of the destination string. # translation continues until a translated byte is equal to the escape # byte or until the source string or destination string is exhausted. if # translation is terminated because of escape the condition code v-bit is # set# otherwise it is cleared. if the destination string overlaps the # table, the destination string and registers r0 through r5 are # unpredictable. if the source and destination strings overlap and their # addresses are not identical, the destination string and registers r0 # through r5 are unpredictable. if the source and destination string # addresses are identical, the translation is performed correctly. # # input parameters: # # the following register fields contain the same information that # exists in the operands to the movtuc instruction. # # r0<15:0> = srclen length of source string # r1 = srcaddr address of source string # r2<7:0> = fill escape character # r3 = tbladdr address of 256-byte table # r4<15:0> = dstlen length of destination string # r5 = dstaddr address of destination string # # in addition to the input parameters that correspond directly to # operands to the movtuc instruction, there are other input parameters # to this routine. note that the two inixxxlen parameters are only # used when the movtuc_v_fpd bit is set in the flags byte. # # r2<15:8> = flags instruction-specific status # # the contents of the flags byte must be zero (mbz) on entry to this # routine from the outside world (through the emulator jacket or by # a jsb call). if the initial contents of flags are not zero, the # actions of this routine are unpredictable. # # there are two other input parameters whose contents depend on # the settings of the flags byte. # # movtuc_v_fpd bit in flags is clear # # r0<31:16> = irrelevant # r4<31:16> = irrelevant # # movtuc_v_fpd bit in flags is set # # r0<31:16> = inisrclen initial length of source string # r4<31:16> = inidstlen initial length of destination string # # intermediate state: # # 31 23 15 07 00 # +----------------+----------------+----------------+----------------+ # | initial srclen | srclen | : r0 # +----------------+----------------+----------------+----------------+ # | srcaddr | : r1 # +----------------+----------------+----------------+----------------+ # | delta-pc | xxxx | flags | esc | : r2 # +----------------+----------------+----------------+----------------+ # | tbladdr | : r3 # +----------------+----------------+----------------+----------------+ # | initial dstlen | dstlen | : r4 # +----------------+----------------+----------------+----------------+ # | dstaddr | : r5 # +----------------+----------------+----------------+----------------+ # # output parameters: # # the final state of this instruction (routine) can exist in one of # three forms, depending on the relative lengths of the source and # destination strings and whether a translated character matched the # escape character. # # 1. some byte matched escape character # # r0 = number of bytes remaining in the source string (including # the byte that caused the escape) # r1 = address of the byte that caused the escape # r2 = 0 # r3 = tbladdr address of 256-byte table # r4 = number of bytes remaining in the destination string # r5 = address of byte that would have received the translated byte # # 2. destination string exhausted # # r0 = number of bytes remaining in the source string # r1 = address of the byte that resulted in exhaustion # r2 = 0 # r3 = tbladdr address of 256-byte table # r4 = 0 (number of bytes remaining in the destination string) # r5 = address of one byte beyond end of destination string # # 3. source string exhausted # # r0 = 0 (number of bytes remaining in the source string) # r5 = address of one byte beyond end of source string # r2 = 0 # r3 = tbladdr address of 256-byte table # r4 = number of bytes remaining in the destination string # r5 = address of byte that would have received the translated byte # # condition codes: # # n <- srclen lss dstlen # z <- srclen eql dstlen # v <- set if terminated by escape # c <- srclen lssu dstlen # # side effects: # # this routine uses five longwords of stack. #- .globl vax$movtucvax$movtuc: pushl r4 # store dstlen on stack pushl r0 # store srclen on stack bbs $(movtuc_v_fpd+8),r2,L15 # branch if instruction was interrupted movw (sp),2(sp) # set the initial srclen on stack movw 4(sp),6(sp) # set the initial dstlen on stackL15: movzwl r4,r4 # clear unused bits of dstlen beql L150 # almost done if zero length movzwl r0,r0 # clear unused bits of srclen beql L140 # done if zero length pushl r10 # save r10 so it can hold handler # establish_handler string_accvio movab string_accvio,r10 pushl r7 # we need some scratch registers pushl r6 # # note that all code must now exit through a code path that restores r6 # r7, and r10 to insure that the stack is correctly aligned and that these # register contents are preserved across execution of this routine. # the following initialization routine is designed to make the main loop # execute faster. it performs three actions. # # r7 <- smaller of r0 and r4 (srclen and dstlen) # # larger of r0 and r4 is replaced by the difference between r0 and r4. # # smaller of r0 and r4 is replaced by zero. # # this initializes r0 and r4 to their final states if either the source # string or the destination string is exhausted. in the event that the loop # is terminated through the escape path, these two registers are readjusted # to contain the proper values as if they had each been advanced one byte # for each trip through the loop. subl2 r0,r4 # replace r4 with (r4-r0) blssu L110 # branch if srclen gtru dstlen # code path for srclen (r0) lequ dstlen (r4). r4 is already correctly loaded. movl r0,r7 # load r7 with smaller (r0) clrl r0 # load smaller (r0) with zero brb L120 # merge with common code at top of loop # code path for srclen (r0) gtru dstlen (r4). L110: movzwl 16(sp),r7 # load r7 with smaller (use saved r4) mnegl r4,r0 # load larger (r0) with abs(r4-r0) clrl r4 # load smaller (r4) with zero # the following is the main loop in this routine. # MARK_POINT MOVTUC_1 .text 2 .set table_size, table_size + 1 .word Lmovtuc_1 - module_base .text 3 .word movtuc_1 - module_base .textLmovtuc_1:L120: movzbl (r1)+,r6 # get next character from source string # MARK_POINT MOVTUC_2 .text 2 .set table_size, table_size + 1 .word Lmovtuc_2 - module_base .text 3 .word movtuc_2 - module_base .textLmovtuc_2: movzbl (r3)[r6],r6 # convert to translated character cmpb r2,r6 # does it match escape character? beql escape # exit loop if yes # MARK_POINT MOVTUC_3 .text 2 .set table_size, table_size + 1 .word Lmovtuc_3 - module_base .text 3 .word movtuc_3 - module_base .textLmovtuc_3: movb r6,(r5)+ # move translated character to # destination string sobgtr r7,L120 # shorter string exhausted? # the following exit path is taken when the shorter of the source string and # the destination string is exhaustedL130: movq (sp)+,r6 # restore contents of scratch register movl (sp)+,r10 # restore saved r10L140: clrl r2 # r2 must be zero on output ashl $-16,(sp),(sp) # get initial srclen ashl $-16,4(sp),4(sp) # get initial dstlen cmpl (sp)+,(sp)+ # set condition codes (v-bit always 0) rsb # return # this code executes if the destination string has zero length. the source # length is set to a known state so that the common exit path can be taken.L150: movzwl r0,r0 # clear unused bits of srclen brb L140 # exit through common code # this code executes if the escape character matches the entry in the # 256-byte table indexed by the character in the source string. registers # r0 and r4 must be adjusted to indicate that neither string was exhausted. # the last step taken before return sets the v-bit.escape: decl r1 # reset r1 to correct byte in source clrl r2 # r2 must be zero on output addl2 r7,r0 # adjust saved srclen addl2 r7,r4 # adjust saved dstlen movq (sp)+,r6 # restore contents of scratch registers movl (sp)+,r10 # restore saved r10 ashl $-16,(sp),(sp) # get initial srclen ashl $-16,4(sp),4(sp) # get initial dstlen cmpl (sp)+,(sp)+ # set condition codes (v-bit always 0) bispsw $psl$m_v # set v-bit to indicate escape rsb # return #+ # functional description: # # the bytes of string 1 specified by the length and address 1 operands are # compared with the bytes of string 2 specified by the length and address # 2 operands. comparison proceeds until inequality is detected or all the # bytes of the strings have been examined. condition codes are affected # by the result of the last byte comparison. two zero length strings # compare equal (i.e. z is set and n, v, and c are cleared). # # input parameters: # # r0<15:0> = len length of character strings # r1 = src1addr address of first character string (called s1) # r3 = src2addr address of second character string (called s2) # # intermediate state: # # 31 23 15 07 00 # +----------------+----------------+----------------+----------------+ # | delta-pc | xxxx | len | : r0 # +----------------+----------------+----------------+----------------+ # | src1addr | : r1 # +----------------+----------------+----------------+----------------+ # | xxxxx | : r2 # +----------------+----------------+----------------+----------------+ # | src2addr | : r3 # +----------------+----------------+----------------+----------------+ # # output parameters: # # strings are identical # # r0 = 0 # r1 = address of one byte beyond end of s1 # r2 = 0 (same as r0) # r1 = address of one byte beyond end of s2 # # strings do not match # # r0 = number of bytes left in strings (including first byte # that did not match) # r1 = address of nonmatching byte in s1 # r2 = r0 # r3 = address of nonmatching byte in s2 # # condition codes: # # in general, the condition codes reflect whether or not the strings # are considered the same or different. in the case of different # strings, the condition codes reflect the result of the comparison # that indicated that the strings are not equal.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -