【问题标题】:Want to use Labels to simplify Little Man Computer Program BubbleSort想用Labels简化小人电脑程序BubbleSort
【发布时间】:2020-11-15 18:17:12
【问题描述】:

这段代码是一个小人计算机程序,它对输入、输出进行冒泡排序和使用,并对自身进行排序,然后重复。这是程序,但我想为所有常量、变量和分支目标位置使用标签,以帮助简化代码并使其更具可读性。我不确定使用什么标签名称来提高可维护性。不需要数字代码。只有行号、标签、助记符数据和 cmets。

000 IN      9001      // input count
001 STO 090 3090 // store count
002 LDA 096 5096 // STO
003 ADD 095 1095 // Determine first location
004 STO 011 3011 // Overwrite STO instruction for list
005 ADD 090 1090
006 STO 092 3092 // Store STO + LOC + Count to determine end
007 LDA 011 5013 // Load manipulated instruction (using as counter)
008 SUB 092 2092 //
009 BRZ 016 7016 // If last count, go to END INPUT LIST
010 IN 9001   
011 DAT 0        // manipulated instruction (store input in list)
012 LDA 011 5011
013 ADD 098 1098 // increment store instruction (to next list location)
014 STO 011 3011 // Update STO instruction
015 BR 007 6007 // GOTO INPUT LIST LOOP
016 LDA 098 5098
017 SUB 090 2090 // 1 – count
018 BRP 061 8061 // GO TO END I LOOP
019 LDA 099 5099
020 STO 092 3092 // set I to zero (0)
021 LDA 090 5090
022 SUB 098 2098 // COUNT - 1
023 SUB 092 1092 // COUNT -1 – I
024 BRZ 061 7061 // if(I == count - 1) GOTO END I LOOP
025 LDA 090 5090
026 SUB 098 2098
027 STO 093 3093 // J = Count – 1
028 LDA 092 5092 // I
029 SUB 093 2093 // I - J
030 BRP 057 8057 // If I == j, then GO END J LOOP
031 LDA 097 5097 // load LDA instruction numeric code
032 ADD 095 1095 // set to LDA 500
033 ADD 093 1093 // set to LDA [500 + j] or A[j]
034 STO 039 3039 // reset instruction
035 SUB 098 2098 // set to LDA [500 + j – 1] or A[j-1]
036 STO 037 3037 // reset instruction
037 DAT 0 // load A[j-1] (instruction is manipulated)
038 STO 088 3088
039 DAT 0 // load A[j] (instruction is manipulated)
040 STO 089 3089
041 SUB 088 2088 // A[j] – A[j-1] (swap if not positive)
042 BRP 053 8053 // GOTO DECREMENT J
043 LDA 096 5096 // load STO instruction code
044 ADD 095 1095 // set to STO 500
045 ADD 093 1093 // set to STO [500 + j]
046 STO 052 3052 // reset instruction
047 SUB 098 2098 // set to STO [500 + j – 1]
048 STO 050 3050 // reset instruction
049 LDA 089 5089 // load A[j]
050 DAT 0 // Store in A[j-1] (instruction is manipulated)
051 LDA 088 5088 // load A[j-1]
052 DAT 0 // Store in A[j] (instruction is manipulated)
053 LDA 093 5093
054 SUB 098 2098
055 STO 093 3093 // J = J – 1
056 BR 028 6028 // GOTO START J LOOP
057 LDA 092 5092
058 ADD 098 1098
059 STO 092 3092 // I = I + 1
060 BR 021 6021 // GOTO START I LOOP
061 LDA 090 5090 // Count
062 OUT 9002
063 LDA 097 5097
064 ADD 095 1095 // LDA + LOC
065 STO 071 3071 // set up instruction
066 ADD 090 1090 // LDA + LOC + Count
067 STO 092 3092 // store unreachable instruction
068 LDA 071 5071 // load manipulated instruction (used as counter)
069 SUB 092 2092
070 BRZ 077 7077 // GOTO END OUTPUT LOOP
071 DAT 0 // manipulated output
072 OUT 9002
073 LDA 071 5071
074 ADD 098 1098
075 STO 071 3071 // increment manipulated instruction
076 BR 068 6028 // GOTO OUTPUT LIST LOOP
077 BR 0 6000 // Branch to top of loop (embedded)
078 HLT 0 // (Should never hit this instruction)
088 DAT 0 // A[j-1] value (also used for swapping)
089 DAT 0 // A[j] value (also used for swapping)
090 DAT 0 // count variable (input and output)
091 DAT 0 // unused
092 DAT 0 // ‘I’ counter
093 DAT 0 // ‘j’ counter
094 DAT 0 // unused
095 DAT 500 // initial list location
096 DAT 3000 // STO instruction
097 DAT 5000 // LDA instruction
098 DAT 1 // one (constant)
099 DAT 0 // zero (constant)

【问题讨论】:

    标签: assembly label little-man-computer


    【解决方案1】:

    只需使用 cmets 作为标签的灵感。不是任何操作目标的行可以不带标签。比如:

    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 位数字的 LMC。

    • 代码不是很简洁:它使用了 98 个邮箱,不包括输入数据所需的存储空间。它可以用更少的东西来完成。例如,this implementation 使用 75 个邮箱。

    • 您写的是需要行号,但是当您使用标签时,行号(即邮箱号)变得无关紧要:LMC 汇编器可以在汇编期间分配它们。

    在标准的 100 邮箱 LMC 上运行

    在您的 cmets 之后,我在此提供您的代码版本,该版本适用于标准 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 中是必需的:

    • 操作码是 3 位,而不是 4 位;
    • 邮箱地址是 2 位,而不是 3 位(所以 500 是不可接受的);
    • 最好只使用下一个可用地址作为列表的位置,而不是硬编码的邮箱地址。

    我还删除了定义未使用邮箱的两行。

    最后,我会将两个BRZ 指令更改为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>

    【讨论】:

    • 是的,我明白你的意思。这更好,因为它需要被简化,所以另一个是一个更简单的程序。谢谢。
    • 就您提供的上面标记的代码而言,我卡在第 11 行 storeInput DAT 上。它一直在说不好的指令。
    • 我必须编辑这行 11 DAT 但不知道该放什么。
    • 您使用的是哪个模拟器/模拟器?也许它不喜欢看到 DAT 后面没有值。您可以添加 0。如果不接受,则将 DAT 替换为其他任何内容,因为它在第一次执行之前被覆盖。例如,您也可以输入STA 0。对于一些类似的行,您将遇到相同的问题。合规的 LMC 模拟器不应该对此产生任何问题...
    • 它在所有 LMC 模拟器上都运行。我尝试在 DAT 之后使用 0 值,但没有成功。我尝试了STA 0 仍然没有成功。你能像其他代码一样把它放在代码 sn-p 中吗?
    猜你喜欢
    • 1970-01-01
    • 2017-10-24
    • 1970-01-01
    • 1970-01-01
    • 2020-07-22
    • 1970-01-01
    • 2021-02-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多