Search code examples
little-man-computer

LMC program do not output the correct sum


loop    inp
        sta numa
        sub validate
endthis brp loop
        bra label1
label1  lda numa
        sub validate1
        brp label2
        brz label2
endthis bra loop
label2  lda num
loop    sta num
        add total
        sta total
        sta num
        sub one
        brp loop
        lda total
        out
validate dat 11
validate1 dat 5
numa    dat
num     dat
total   dat 
one     dat 1

This program will let the user to input the number between 5 to 10 and calculate the sum of the numbers from 1 to the input specified by user and print the result in the output display. For example, if the user input 5, the sum will be 15.


Solution

  • There are the following issues with the code:

    • Some labels are not unique, like loop. So that means it is not clear where the execution should jump with the brp loop instruction. Depending on which simulator you use, you can get different behaviours. You should use unique names for the labels.

    • The second part of your code -- where the calculation is done -- starts with:

      label2  lda num
      loop    sta num
      

      ... but that just reads and writes what is in num, which is useless. You really want to copy the input to num, and so this should be:

      label2  lda num2
      loop    sta num
      
    • A bit further down the code you have this:

      sta total
      sta num
      sub one
      

      ...but this overwrites num with the total, and then subtracts one from the total. Yet, you want to subtract one from the value that is counting down from the input number, not from the total. So what you really need here is to get that count-down value and then subtract:

      sta total
      lda num    # corrected
      sub one
      
    • Your program does not have a hlt instruction, which means execution will fall-through into the "data section" of your program. So add hlt here:

      lda total
      out
      hlt    # stop execution
      

    There are also the following things to improve:

    • The endthis label is never referenced: it is not needed.

    • In this code:

      brp label2
      brz label2
      

      ... the brz instruction will never result in a jump to label2, because a zero is already captured by brp. It may be confusing, but brp means: "branch when not negative", so it also branches when the accumulator is zero. Therefore you can just remove that brz label2; it is not needed.

    • The following bra instruction:

              bra label1
      label1  lda numa
      

      ... will jump to label1 or else just proceed with that line also. So it is a useless jump. You can just take out that bra label1 line, and remove the label also.

    • A LMC can be reset to run again from the top. In that case you must take into account that the data is not reset, and so it is good practice to have code that initialises data to initial values at the start of your program. In this particular case, you'll want to reset the total back to 0, as otherwise you'll be adding to the total of a previous run.

    • I would suggest using more meaningful names. For example, label1 and numa are not really clarifying what they are used for.

    Suggested solution:

              lda zero   # added: initialise total
              sta total
    getinput  inp
              sta input
              sub toogreat
              brp getinput
              lda input
              sub minimum
              brp inputok
              bra getinput
    inputok   lda input     # corrected
    loop      sta countdown
              add total
              sta total
              lda countdown # corrected
              sub one
              brp loop
              lda total
              out
              hlt   # added
    toogreat  dat 11
    minimum   dat 5
    input     dat 4
    countdown dat
    total     dat 0 
    zero      dat 0
    one       dat 1
    
    <script src="https://cdn.jsdelivr.net/gh/trincot/[email protected]/lmc.js"></script>