私は与えられた数をLC3の異なるベースに変換する必要がある割り当てに取り組んでいます。これを行うには、除算を使用する必要があります。また、同じことを行った代入がある間に、この除算アルゴリズムは異なります。トラップがLC3の不正なベクタ番号で実行されました
この割り当てでは、拡張除算を使用することが予想されます。
32ビットの数値を指定すると、最初の16ビットをメモリアドレス(高分子と呼ばれます)に格納し、最後の16ビット(低分子)を別の1ビットに、除数を別の16ビットビット数を別のビット数に変換します。だから、サブルーチンに、番号が異なるレジスタにメモリからフェッチされると、次のようなアルゴリズムが働くだろう:
- 高い分子および低分子のためのレジスタがあれば、高ビットように(後左にシフトされている両方(左端)が1である場合、それは高分子の下位ビットに渡される。これはシフトされているので、ゼロでなければならない。)
- 高い分子が除数と比較される。それ以上であれば、除数を減算して低分子の下位ビットを設定します。そうでない場合は、何もしないでください(最終的にシフトを続けると、結果は大きくなります)
- シフトを繰り返して、分子の下位ビット(右端)を設定して16回確認してください。
- 最後に、高い分子は除算の残りの部分を保持し、分子が小さいレジスタは商を保持します
わかりやすくするために、私たちの指導者は0を高分子として使用しています。
- まず、私は5の.BLKWを宣言し、名前の引数リスト、すべての引数が
- PRINTサブルーチンを格納されます::だから、アルゴリズムを満たすために、私は、次の手順を思い付いた私は宣言するすべてのST演算は、作業用レジスタの値をサブルーチンで使用されるものとは別の値に保つために、ARGLISTのアドレスをレジスタにロードします。レジスタには低分子が格納され、インクリメントは高分子0)and divisor>次に、BUFFERとDIGITSのポインタにロードして、指定されたベースに変換した結果を格納します。次に、DIVIDEサブルーチンは
- DIVIDEサブルーチンと呼ばれます:私はARGLISTのアドレスをレジスタにロードし(割り当て命令に従ってR6)、値を準備するために必要なレジスタにロードし、インクリメントし、 (低い分子の高いビットを得るためにx0080でマスキングが行われます)、DVRが高分子以下で繰り返されるたびに減算します。次に、商と余りが格納され、R6が指し示されている場所に格納されます(もちろん、次のレコードに進むためにインクリメントします)。
- PRINTに戻って、R2とR3にロードします。 R7が指している値から、ARGLISTをポイントするので、サブルーチンは割り当て2と同様に続行します。
- バッファに格納された全体が発生したとき、 「更新」に引数リストの先頭に商に低分子とのポイントは次の反復(次の除算)以下
の準備ができなければ、私が持っている完全なコードは、これまでのところです:
.ORIG x3000
LEA R0, MPROMPT
TRAP x22
LOOP
JSR GETDEC ;Input an unsigned (decimal) integer
ADD R0, R0, #0 ;Exit if the input integer is 0
BRZ EXIT
JSR NEWLN ;Move cursor to the start of a new line
AND R1, R1, #0 ;R1 = 10 (output base 10 DECIMAL)
ADD R1, R1, #10
JSR PRINT ;Print the integer in decimal
JSR NEWLN ;Move cursor to the start of a new line
AND R1, R1, #0 ;R1 = 2 (output base 2 BINARY)
ADD R1, R1, #2
JSR PRINT ;Print the integer in binary
JSR NEWLN ;Move cursor to the start of a new line
AND R1, R1, #0 ;R1 = 8 (output base 8 OCTAL)
ADD R1, R1, #8
JSR PRINT ;Print the integer in octal
JSR NEWLN ;Move cursor to the start of a new line
AND R1, R1, #0 ;R1 = 16 (output base 16 HEXADECIMAL)
ADD R1, R1, #15
ADD R1, R1, #1
JSR PRINT ;Print the integer in hexadecimal
JSR NEWLN ;Move cursor to the start of a new line
BRNZP LOOP
EXIT ;Loop exit point
TRAP x25 ;HALT program execution
MPROMPT .STRINGZ "Enter a sequence of unsigned integer values\nEnter 0 To Quit\n"
;Subroutine NEWLN*************************************************************
;Advances the console cursor to the start of a new line
NEWLN
ST R7, NEW7 ;Save working registers
ST R0, NEW0
LD R0, NL ;Output a newline character
TRAP x21
LD R0, NEW0 ;Restore working registers
LD R7, NEW7
RET ;Return
;Data
NL .FILL x000A ;Newline character
NEW0 .BLKW 1 ;Save area - R0
NEW7 .BLKW 1 ;Save area - R7
;Subroutine GETDEC************************************************************
;Inputs an unsigned integer typed at the console in decimal format
;The input value is returned in R0
GETDEC
;Save Values of ALL Registers that don't need to change
ST R1, GET1
ST R2, GET2
ST R3, GET3
ST R4, GET4
ST R5, GET5
ST R6, GET6
ST R7, GET7 ;Save R7 to be able to return to main
AND R3, R3, #0 ;Prepare a value
LEA R0, GPROMPT
TRAP x22
GETDKEY
TRAP x20 ;To input a keystroke
ADD R2, R0, #-10 ;Subtract new keystroke by 10 (new line, or enter)
BRZ GFINIS ;If R2 is 0 we just pressed enter, so we break out
TRAP x21 ;Echo keystroke
ADD R2, R0, #0 ;Get the number back
AND R2, R2, #15 ;We mask to only get the first four bits
ADD R3, R3, R3 ;1st addition: x + x = 2x
ADD R4, R3, #0 ;Store the 2x
ADD R3, R3, R3 ;2nd addition: 2x + 2x = 4x
ADD R3, R3, R3 ;3rd addition: 4x + 4x = 8x
ADD R3, R3, R4 ;4th addition: 8x + 2x = 10x
ADD R3, R3, R2 ;10x + new number
BRNZP GETDKEY ;Go back to get next number
GFINIS
ADD R0, R3, #0 ;Put number into R0
;Restore the values of registers that don't need change
LD R1, GET1
LD R2, GET2
LD R3, GET3
LD R4, GET4
LD R5, GET5
LD R6, GET6
LD R7, GET7 ;Get back the value of R7
RET
;Data
GPROMPT .STRINGZ "Enter an unsigned integer> " ;Input Prompt
GET1 .BLKW 1
GET2 .BLKW 1
GET3 .BLKW 1
GET4 .BLKW 1
GET5 .BLKW 1
GET6 .BLKW 1
GET7 .BLKW 1
;Subroutine PRINT*************************************************************
;Displays an unsigned integer in any base up to 16, e.g. binary, octal, decimal
;Parameters - R0: the integer - R1: the base
PRINT
ST R0, PR0
ST R1, PR1
ST R2, PR2
ST R3, PR3
ST R4, PR4
ST R5, PR5
ST R6, PR6
ST R7, PR7
LEA R7, ARGLIST ;Point to ARGLIST to start populating the args
STR R0, R7, #0 ;Put R0 to be the low numerator
AND R0, R0, #0 ;R0 is not needed after this, so it is cleared
ADD R7, R7, #1 ;Go down on pointer once to store next arg
STR R0, R7, #0 ;Put R0, now x0000, to be the high numerator
ADD R7, R7, #1
STR R1, R7, #0 ;Store the base, R1, to be the DVR
ADD R7, R7, #1 ;Have R7 point to Quotient
LEA R6, BUFFER
AND R5, R5, #0 ;To make sure R5 is cleared
LEA R4, DIGITS ;Prepare pointer to the digits
SDIV
JSR DIVIDE
LDR R2, R7, #0 ;Since the addresses should now be ready,
;R7 would point to quotient, passed to R2
LDR R3, R7, #1 ;Pass remainder to R3
ADD R3, R3, R4
LDR R5, R3, #0
ADD R6, R6, #-1 ;Decrement to get to the next one
STR R5, R6, #0 ;Store number into buffer
LEA R7, ARGLIST ;Go back to ARGLIST to store new numerator
STR R2, R7, #0
ADD R7, R7, #3 ;Point to quotient
ADD R0, R2, #0 ;Pass quotient into R0
BRP SDIV ;If number is at least 1, then divide again
ADD R0, R6, #0 ;If we got here, then we should have the converted number
TRAP x22 ;Last but not least we display
LD R0, PR0
LD R1, PR1
LD R2, PR2
LD R3, PR3
LD R4, PR4
LD R5, PR5
LD R6, PR6
LD R7, PR7
RET
;Data
DIGITS .STRINGZ "ABCDEF" ;Digits
.BLKW 18 ;Output Buffer
BUFFER .FILL x0000 ;Null
PR0 .BLKW 1
PR1 .BLKW 1
PR2 .BLKW 1
PR3 .BLKW 1
PR4 .BLKW 1
PR5 .BLKW 1
PR6 .BLKW 1
PR7 .BLKW 1
;Subroutine DIVIDE************************************************************
;Extended division is done here
DIVIDE
ST R1, DIV1
ST R2, DIV2
ST R3, DIV3
ST R4, DIV4
ST R5, DIV5
ST R6, DIV6
ST R7, DIV7
LEA R6, ARGLIST ;Point straight to where arguments start
LDR R5, R6, #0 ;Load NUMLOW into R5
ADD R6, R6, #1 ;Go down one step in pointer
LDR R4, R6, #0 ;Load NUMHIGH into R4
ADD R6, R6, #1 ;Go down once more
LDR R3, R6, #0 ;Load DVR into R3
ADD R6, R6, #1 ;Go down yet once more to be ready when we
;store results
LD R1, M8BIT ;Make R1 be equal to x0080 to get last bit
;from NUMLOW
AND R2, R2, #0 ;Set R2 as counter to decrement with each
ADD R2, R2, #10 ;iteration
ADD R2, R2, #6
ITER ADD R4, R4, R4 ;Shift NUMHIGH to the left once
AND R7, R5, R1 ;Masking. If R5[7] == 1, then R7 == x0080
BRNZ NOADD ;(or positive)
ADD R4, R4, #1 ;If this happens then R5[7] was set, so we're
;adding the bit that would be lost if R5
;shifts left
NOADD ADD R5, R5, R5 ;Shift NUMLOW to the left once
NOT R7, R3 ;Subtract NUMHIGH and DVR. If 0 or positive
ADD R7, R7, #1 ;then subtract and increment NUMLOW
ADD R7, R4, R7
BRN DECCNT ;If negative then DVR is greater than NUMHIGH,
;go straight to decrement the loop count
ADD R4, R7, #0
ADD R5, R5, #1
DECCNT ADD R2, R2, #-1
BRP ITER ;If count is positive, go back to ITER
STR R5, R6, #0 ;Store NUMLOW for the Quotient Address
ADD R6, R6, #1 ;Increment to store in the next one
STR R4, R6, #0 ;Store NUMHIGH for the Remainder Address
LD R1, DIV1
LD R2, DIV2
LD R3, DIV3
LD R4, DIV4
LD R5, DIV5
LD R6, DIV6
LD R7, DIV7
RET ;Return
;Data
ARGLIST .BLKW 5 ;Here we will put the LOWNUM, HIGHNUM,
;DVR, QUO, and REM
M8BIT .FILL x0080
DIV1 .BLKW 1
DIV2 .BLKW 1
DIV3 .BLKW 1
DIV4 .BLKW 1
DIV5 .BLKW 1
DIV6 .BLKW 1
DIV7 .BLKW 1
.END
私はアルゴリズムが働くべきだと思うが、私はLC3上でそれを実行するように、私は次のエラーを取得:
A trap was executed with an illegal vector number
をし、プロセッサが停止しています。再びDIVIDEサブルーチンを呼び出すために分岐する前に、右のだろう
ADD R0, R2, #0
:何らかの理由で、私はLC3に自分のコードをチェックしたときにそれが適切なこの行の後に消去されることを気づきました。
なぜこれが起こっていますか?私が知る限りでは、私はレジスタを適切に保存して復元しています(前回同様の問題があり、エラーを起こした.BLKWに保存していたと指摘していました)が、エラー持続する。何が誤動作しているのか、さらに必要な情報があれば誰にでも知らせてください。助けをありがとうございます。