简单的LC3计算器

时间:2015-02-04 21:42:44

标签: assembly lc3

我正在编写一个程序来接受以下字符之一的用户输入,0-9,+, - ,*,/和^。它一次只需要两个操作数,并以反向抛光表示法,例如,5 6 +或2 8 /。除了用户输入部分,我已经弄明白了。我知道使用GETC和OUT但我不明白这两个函数是如何工作的,因此在程序开始时很难实现它们。这就是我所拥有的。它目前编译时没有错误,但它似乎无法正常工作。

; INTRO PARAGRAPH
;我将从定义我的寄存器使用开始。 R0保存用户输入的最后一个字符。 R1,R2,R3和R4 ;都只是临时寄存器,它们保存的值只对即时任务很重要。 R6是我的堆栈指针 ; R5是我用来从堆栈中获取信息的东西。我首先将所有寄存器初始化为零。从那里我取 ;用户输入的最后一个字符,并通过条件对其进行过滤,以找出它是什么字符以及子程序
;发送给。如果是0-9,则将其推入堆栈。如果它是无效字符,则跳转到
;输出消息的INVALID_CHARACTER循环然后终止程序。如果是操作员,则将其发送到DECODE,其中为 ;它的十六进制值被反转,然后通过几个条件发送,以找出它是哪个运算符和哪个循环
;发送给。寄存器使用在操作员循环上方说明,如果它可能混淆每个寄存器是什么 ;被用来。最后,程序将在看到新行字符时终止。在这里,我将xA设置为新行
;字符。

                    .ORIG x3000

    ;initializes all registers to zero
                    AND R0, R0, #0
                    AND R1, R1, #0
                    AND R2, R2, #0
                    AND R3, R3, #0
                    AND R4, R4, #0
                    AND R5, R5, #0
                    AND R6, R6, #0
                    AND R7, R7, #0

    ;this block will ask for user input then display it to the monitor

    NEXTCHARACTER           GETC
                            OUT

    ;reads input and determines whether or not it is a valid character

    ;Space?
                    LD R1, OPPOSPACE 
                    ADD R1, R0, R1
                    BRz NEXTCHARACTER

   ;New line?
                    LD R1, OPPOLINE
                    ADD R1, R0, R1
                    BRz DONE

   ;Multiplication?
                    LD R1, OPPOMULTI
                    ADD R1, R0, R1
                    BRz DECODE
                    Brn INVALID_CHARACTER

    ;Exponent?
                    LD R1, OPPOEXPO
                    ADD R1, R0, R1
                    BRz DECODE
                    Brp INVALID_CHARACTER

    ;Is at most 9? 
                    LD R1, OPPOCOLON
                    ADD R1, R0, R1
                    Brzp INVALID_CHARACTER

    ;Is it an apostrophe?
                    LD R1, OPPOAPOST
                    ADD R1, R0, R1
                    BRz INVALID_CHARACTER

    ;Is it a decimal point?
                    LD R1, OPPODECI
                    ADD R1, R1, R0
                    BRz INVALID_CHARACTER

    ;Operand or operator?
                    LD R1, OPPOZERO
                    ADD R1, R1, R0
                    BRzp PUSH
                    BRn DECODE

    INVALID_CHARACTER       .STRINGZ "Error invalid input"
                    BRnzp DONE

    ERROR                   .STRINGZ "operation jumps are incorrect"
                    BRnzp DONE

    ;stores negation of operators in stack
    DECODE                  NOT R0, R0
                    ADD R0, R0, #1          ;stores the opposite hex value 

    ;figure out what operation to jump to
                    LD R1, ADDING
                    ADD R1, R1, R0
                    BRz ADDITION            ;jumps to addition sequence 

                    LD R1, SUBTRACT
                    ADD R1, R1, R0
                    BRz SUBTRACTION         ;jumps to subtraction sequence

                    LD R1, MULTI
                    ADD R1, R1, R0
                    BRz MULTIPLICATION      ;jumps to multiplication seq

                    LD R1, DIVIDE
                    ADD R1, R1, R0
                    Brz DIVISION            ;jumps to division sequence

                    LD R1, EXPONENT
                    ADD R1, R1, R0
                    BRz EXPONENTIAL         ;jumps to exponent sequence
                    Brnp ERROR

    ;pushes and pops characters into and out of the stack
    PUSH            ADD R6, R6, #-1         ;moves stack pointer up 
                    STR R0, R6, #0          ;stores R0 at current spot
                    BRnzp NEXTCHARACTER

    POP             LDR R5, R6, #0          ;loads  R6 into R5
                    ADD R6, R6, #1          ;moves stack pointer 

    ;here are the operations
    ;R2 and R3 are operands R2 holds answer                     
    ADDITION        ADD R2, R5, #0          ;loads first number  into R2

                    LDR R5, R6, #0          ;loads  R6 into R5
                    ADD R6, R6, #1          ;moves stack pointer 

                    ADD R3, R5, #0          ;loads second number  into R2
                    ADD R2, R2, R3          ;stores answer in R2

                    ADD R6, R6, #-1         ;moves stack pointer up 
                    STR R2, R6, #0          ;stores R2 in empty spot 
                    BRnzp NEXTCHARACTER     ;goes back to user input to read 

    SUBTRACTION     ADD R3, R5, #0          ;loads number into R3

                    LDR R5, R6, #0
                    ADD R6, R6, #1          ;moves pointer 

                    ADD R2, R5, #0          ;loads digit to be added into R2
                    NOT R3, R3  
                    ADD R3, R3, #1          ;2's complement of R3
                    ADD R2, R2, R3          ;subtraction of the two numbers

                    ADD R6, R6, #-1         ;moves stack pointer up 
                    STR R2, R6, #0          ;stores R2 in empty spot 

                    BRnzp NEXTCHARACTER     ;goes back to user input to read 

    MULTIPLICATION  ADD R2, R5, #0          ;loads number to be multiplied

                    LDR R5, R6, #0
                    ADD R6, R6, #1          ;moves pointer 

                    ADD R3, R5, #0          ;loads number to be multiplied 

    MULTIPLICATIONLOOP      ADD R2, R3, R2
                    ADD R3, R3, #-1
                    BRp MULTIPLICATIONLOOP

                    ADD R6, R6, #-1         ;moves stack pointer up 
                    STR R2, R6, #0          ;stores R2 in empty spot 

                    BRnzp NEXTCHARACTER     ;goes back to user input to read 

    ;R1 will be a place holder here
    ;R4 will hold quotient
    ;R5 will hold remainder
    ;R2 is dividend
    ;R3 is divisor
    DIVISION        ADD R3, R5, #0          ;loads divisor

                    LDR R5, R6, #0
                    ADD R6, R6, #1          ;moves pointer after loading R5

                    ADD R2, R5, #0          ;loads dividend

                    NOT R1, R3          
                    ADD R1, R1, #1
    DIVLOOP         ADD R4, R4, #1
                    AND R2, R2, R0
                    BRn NEGATIVE
                    BRp DIVLOOP
                    BRz ZERO
    NEGATIVE        ADD R4, R4, #-1
                    ADD R5, R2, R3

                    ADD R6, R6, #-1         ;moves stack pointer up   
                    STR R4, R6, #0          ;stores R4 in empty spot 

    ZERO            BRnzp NEXTCHARACTER     ;goes back to user input to read 

    ;R2 is exponent
    ;R3 is base and answer
    ;R4 is base copy
    ;R1 is base copy
    EXPONENTIAL             ADD R2, R5, #0          ;loads exponent into R2

                    LDR R5, R5, #0
                    ADD R6, R6, #1          ;moves pointer after loading R5

                    ADD R3, R5, #0          ;loads base into R3
                    ADD R1, R1, R3          ;loads base into R1
    OUTEREXPOLOOP   ADD R4, R1, #0          ;loads base into R4 for counter
    INNEREXPOLOOP   ADD R3, R3, R3          ;starts multiplication sequence
                    ADD R4, R4, #-1         ;decrements base counter
                    BRp INNEREXPOLOOP
                    ADD R2, R2, #-1         ;determines if needs to re-enter 
                    BRp OUTEREXPOLOOP   

                    ADD R6, R6, #-1         ;moves stack pointer up 
                    STR R3, R6, #0          ;stores R3 in empty spot 

                    BRnzp NEXTCHARACTER     ;goes back to user input to read 


    DONE                    HALT


    MULTI           .FILL x002A
   EXPONENT         .FILL x005E
   ADDING           .FILL x002B
    SUBTRACT        .FILL x002D
    DIVIDE          .FILL x002F
    OPPOSPACE       .FILL xFFDF
    OPPOLINE        .FILL xFFF5
    OPPOMULTI       .FILL xFFD5
    OPPOEXPO        .FILL xFFA1
    OPPOCOLON       .FILL xFFC5
    OPPOAPOST       .FILL xFFD3
    OPPODECI        .FILL xFFD1
    OPPOZERO        .FILL xFFCF
    STACK_START     .FILL x5000
    STACK_POINTER   .FILL x5000
    STACK_TOP       .FILL x5050
    OPPOSTART       .FILL xAFFF

    .END

1 个答案:

答案 0 :(得分:1)

您通常会使用GETC提示来获取用户的输入。 GETC等待来自用户的字符输入并将其保存在R0中。在您拥有.FILL事物的程序的底部,您可以创建如下提示:

PROMPT    .STRINGZ    "Enter a number or operation: "

要在程序中显示并获取输入,您可以执行以下操作:

LEA    R0, PROMPT    ;Save the location of the prompt
PUTS                 ;Print the prompt to the screen
GETC                 ;Store the character into R0

OUT与GETC相反。它需要一个存储在R0中的单个字符并将其打印到屏幕上。因此,要回显用户输入的字符(以便他们可以看到他们输入的内容),您只需在GETC下面添加一个OUT行。

OUT                 ;Echo character to the screen