ラベルのインスピレーションとしてコメントを使用してください。どの操作の対象でもない行は、ラベルなしで移動できます。たとえば、次のようになります。
start IN // input count
STO count // store count
LDA stoInstruction // STO
ADD location // Determine first location
STO storeInput // Overwrite STO instruction for list
ADD count
STO i // Store STO + LOC + Count to determine end
loopInput LDA storeInput // Load manipulated instruction (using as counter)
SUB i //
BRZ exitInputLoop // If last count, go to END INPUT LIST
IN
storeInput DAT // manipulated instruction (store input in list)
LDA storeInput
ADD one // increment store instruction (to next list location)
STO storeInput // Update STO instruction
BR loopInput // GOTO INPUT LIST LOOP
exitInputLoop LDA one
SUB count // 1 – count
BRP exitLoopI // GO TO END I LOOP
LDA zero
STO i // set I to zero (0)
loopI LDA count
SUB one // COUNT - 1
SUB i // COUNT -1 – I
BRZ exitLoopI // if(I == count - 1) GOTO END I LOOP
LDA count
SUB one
STO j // J = Count – 1
loopJ LDA i // I
SUB j // I - J
BRP exitLoopJ // If I == j, then GO END J LOOP
LDA ldaInstruction // load LDA instruction numeric code
ADD location // set to LDA 500
ADD j // set to LDA [500 + j] or A[j]
STO loadCurrent // reset instruction
SUB one // set to LDA [500 + j – 1] or A[j-1]
STO loadPrevious // reset instruction
loadPrevious DAT // load A[j-1] (instruction is manipulated)
STO previous
loadCurrent DAT // load A[j] (instruction is manipulated)
STO current
SUB previous // A[j] – A[j-1] (swap if not positive)
BRP decrementJ // GOTO DECREMENT J
LDA stoInstruction // load STO instruction code
ADD location // set to STO 500
ADD j // set to STO [500 + j]
STO storeCurrent // reset instruction
SUB one // set to STO [500 + j – 1]
STO storePrevious // reset instruction
LDA current // load A[j]
storePrevious DAT // Store in A[j-1] (instruction is manipulated)
LDA previous // load A[j-1]
storeCurrent DAT // Store in A[j] (instruction is manipulated)
decrementJ LDA j
SUB one
STO j // J = J – 1
BR loopJ // GOTO START J LOOP
exitLoopJ LDA i
ADD one
STO i // I = I + 1
BR loopI // GOTO START I LOOP
exitLoopI LDA count // Count
OUT
LDA ldaInstruction
ADD location // LDA + LOC
STO instruction // set up instruction
ADD count // LDA + LOC + Count
STO i // store unreachable instruction
loopOutput LDA instruction // load manipulated instruction (used as counter)
SUB i
BRZ exitLoopOutput // GOTO END OUTPUT LOOP
instruction DAT // manipulated output
OUT
LDA instruction
ADD one
STO instruction // increment manipulated instruction
BR loopOutput // GOTO OUTPUT LIST LOOP
exitLoopOutput BR start // Branch to top of loop (embedded)
HLT // (Should never hit this instruction)
previous DAT // A[j-1] value (also used for swapping)
current DAT // A[j] value (also used for swapping)
count DAT // count variable (input and output)
DAT // unused
i DAT // ‘I’ counter
j DAT // ‘j’ counter
DAT // unused
location DAT 500 // initial list location
stoInstruction DAT 3000 // STO instruction
ldaInstruction DAT 5000 // LDA instruction
one DAT 1 // one (constant)
zero DAT 0 // zero (constant)
ノート:
この LMC は元の LMC の変形で、3 桁の数字がありましたが、4 桁の数字を使用しているようです。
コードはあまり簡潔ではありません。入力データに必要なストレージを除いて、98 個のメールボックスを使用しています。少ない枚数でできます。たとえば、75 個のメールボックスを使用するこの実装を見てください。
行番号が必要であると書いていますが、ラベルを使用すると、行番号 (つまり、メールボックス番号) は無関係になります: LMC アセンブラは、アセンブリ中にそれらを割り当てることができます。
標準の 100 メールボックス LMC で実行
コメントの後、標準の LMC に適合したバージョンのコードをここに提供します。これは、実際の入力データ用に残されたスペースがあまりないことを意味します。データ用に 11 個のメールボックスだけが残されます。
以下の部品を交換する必要がありました。
location DAT 500 // initial list location
stoInstruction DAT 3000 // STO instruction
ldaInstruction DAT 5000 // LDA instruction
...これとともに:
location DAT list // initial list location
stoInstruction DAT 300 // STO instruction
ldaInstruction DAT 500 // LDA instruction
list DAT // start of the list
これは、標準の LMC と同様に必要です。
- オペコードは 4 桁ではなく 3 桁です。
- メールボックス アドレスは 3 桁ではなく 2 桁です (したがって 500 は受け入れられません)。
- ハードコードされたメールボックス アドレスではなく、リストの場所として次に利用可能なアドレスを使用することをお勧めします。
また、未使用のメールボックスを定義する 2 行も削除しました。
最後に、前の命令が負の結果を出したときのアキュムレータの値が理論上保証されていないため、2 つのBRZ
命令を命令で変更します。その場合、アキュムレータの値は信頼できません (負でない値しか持てないため、ウィキペディアを参照してください)。したがって、未定義の値に対して a を実行すると、リスクが生じます。アキュムレータではなくフラグをチェックするため、安全な命令です。BRP
SUB
BRZ
BRP
#input: 3 44 22 99
start IN // input count
STO count // store count
LDA stoInstruction // STO
ADD location // Determine first location
STO storeInput // Overwrite STO instruction for list
ADD count
STO i // Store STO + LOC + Count to determine end
loopInput LDA storeInput // Load manipulated instruction (using as counter)
SUB i //
BRP exitInputLoop // If last count, go to END INPUT LIST
IN
storeInput DAT // manipulated instruction (store input in list)
LDA storeInput
ADD one // increment store instruction (to next list location)
STO storeInput // Update STO instruction
BR loopInput // GOTO INPUT LIST LOOP
exitInputLoop LDA one
SUB count // 1 – count
BRP exitLoopI // GO TO END I LOOP
LDA zero
STO i // set I to zero (0)
loopI LDA count
SUB one // COUNT - 1
SUB i // COUNT -1 – I
BRZ exitLoopI // if(I == count - 1) GOTO END I LOOP
LDA count
SUB one
STO j // J = Count – 1
loopJ LDA i // I
SUB j // I - J
BRP exitLoopJ // If I == j, then GO END J LOOP
LDA ldaInstruction // load LDA instruction numeric code
ADD location // set to LDA 500
ADD j // set to LDA [500 + j] or A[j]
STO loadCurrent // reset instruction
SUB one // set to LDA [500 + j – 1] or A[j-1]
STO loadPrevious // reset instruction
loadPrevious DAT // load A[j-1] (instruction is manipulated)
STO previous
loadCurrent DAT // load A[j] (instruction is manipulated)
STO current
SUB previous // A[j] – A[j-1] (swap if not positive)
BRP decrementJ // GOTO DECREMENT J
LDA stoInstruction // load STO instruction code
ADD location // set to STO 500
ADD j // set to STO [500 + j]
STO storeCurrent // reset instruction
SUB one // set to STO [500 + j – 1]
STO storePrevious // reset instruction
LDA current // load A[j]
storePrevious DAT // Store in A[j-1] (instruction is manipulated)
LDA previous // load A[j-1]
storeCurrent DAT // Store in A[j] (instruction is manipulated)
decrementJ LDA j
SUB one
STO j // J = J – 1
BR loopJ // GOTO START J LOOP
exitLoopJ LDA i
ADD one
STO i // I = I + 1
BR loopI // GOTO START I LOOP
exitLoopI LDA count // Count
OUT
LDA ldaInstruction
ADD location // LDA + LOC
STO instruction // set up instruction
ADD count // LDA + LOC + Count
STO i // store unreachable instruction
loopOutput LDA instruction // load manipulated instruction (used as counter)
SUB i
BRP exitLoopOutput // GOTO END OUTPUT LOOP
instruction DAT // manipulated output
OUT
LDA instruction
ADD one
STO instruction // increment manipulated instruction
BR loopOutput // GOTO OUTPUT LIST LOOP
exitLoopOutput BR start // Branch to top of loop (embedded)
HLT // (Should never hit this instruction)
previous DAT // A[j-1] value (also used for swapping)
current DAT // A[j] value (also used for swapping)
count DAT // count variable (input and output)
i DAT // ‘I’ counter
j DAT // ‘j’ counter
location DAT list // initial list location
stoInstruction DAT 300 // STO instruction
ldaInstruction DAT 500 // LDA instruction
one DAT 1 // one (constant)
zero DAT 0 // zero (constant)
list DAT
<script src="https://cdn.jsdelivr.net/gh/trincot/lmc@v0.815/lmc.js"></script>