反向波兰符号mips算法

反向波兰符号mips算法,mips,Mips,作为一名初学者,我很难掌握mips语言。 最近,我检查了一个MIPS反向波兰符号程序,我在网上从爱丁堡大学找到的,我没有什么问题要问。 强>下面的代码不是我的。它是爱丁堡大学的属性< /强> # ====================================================== # Reverse Polish Notation Calculator # =========================================================

作为一名初学者,我很难掌握mips语言。 最近,我检查了一个MIPS反向波兰符号程序,我在网上从爱丁堡大学找到的,我没有什么问题要问。 <>强>下面的代码不是我的。它是爱丁堡大学的属性< /强>

# ======================================================
# Reverse Polish Notation Calculator
# ===================================================================
# RPN calculator in MIPS
#
# Inf2C-CS Coursework 1. Task B
# SOLUTION
#
# Paul Jackson
# 10 Oct 2012

    #==================================================================
    # DATA SEGMENT
    #==================================================================
    .data
                    # // Global variables in memory
                    # int stack[STACK_SIZE] ;
    .align 2        # // Ensure stack array starts on word boundary
stack:  .space 20       # // Allocate STACK_SIZE * 4 byte words for stack
                    # // where STACK_SIZE = 5.
stack_end:

                    # // String constants
prompt: .asciiz "> "    # char* prompt = "> " ;
newline:
    .asciiz "\n"    # char* newline = "\n" ; 

empty:                  # char* empty = "(EMPTY)\n" // Stack empty message
    .asciiz "(EMPTY)\n" 
colonsp:
    .asciiz ": "    # char* colonsp = ": " // For stack print formatting

    #==================================================================
    # TEXT SEGMENT  
    #==================================================================
    .text

    # // Register usage.
    # //
    # int* stackp ;   // $s0.  Stack pointer
    # int* stack  ;   // $s1.  &stack[0] - Start address of stack 
    # int* stack_end ;// $s2.  &stack[STACK_SIZE] - First address after
    #                 //                            end of stack
    # int  c          // $s3.  Input character (coerced to int)

    # int  s4 // $s4 Temporary var preserved across function calls
    # int  s5 // $s5 Temporary var preserved across function calls

    #------------------------------------------------------------------
    # PUSH FUNCTION
    #------------------------------------------------------------------
                          # void push (int i) 
                          # i in $a0
push:                         # {
                          #     if (stackp < stack_end) 
    slt  $t1, $s0, $s2    #         // $t1 = stackp < stack_end
    beqz $t1, push_end    #         // b push_end if $t1 == 0
                          #     {
    sw   $a0, 0($s0)      #         *stackp = i ;
    addi $s0, $s0, 4      #         ++stackp ;
                          #     }
push_end:       
    jr $ra                #     return ;
                          # }


    #------------------------------------------------------------------
    # POP FUNCTION
    #------------------------------------------------------------------
                            # int pop() {

pop:                            #     if (stack < stackp) 
    slt  $t1, $s1, $s0      #         // $t1 = stack < stackp
    beqz  $t1, pop1         #         // branch to pop1 if $t1 == 0
                            #     {
    addi $s0, $s0, -4       #         stackp-- ;
                            #         return *stackp ;
    lw   $v0, 0($s0)        #         // $v0 = *stackp
    jr   $ra                #         // return $v0

                            #     } else {
                            #         return 0 ;
pop1:   li   $v0, 0             #         // $v0 = 0
    jr $ra                  #         // return $v0
                            # }


    #------------------------------------------------------------------
    # MAIN BODY
    #------------------------------------------------------------------
main:
    # Initialisation of registers holding constant values

    la  $s1, stack            # // $s1 = &stack[0];
    la  $s2, stack_end        # // $s2 = &stack[STACK_SIZE];

    # Initialisation of registers for main program variable
    move $s0, $s1             # stackp = stack ;

    li $v0, 4                 # print_string("> ")
    la $a0, prompt
    syscall

    #- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
    # READ LOOP
    #- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 

mainloop:                         # while (1) {


    li $v0, 12                #    c = read_char()
    syscall                 
    move $s3, $v0           

    #- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
    # CASE SWITCH ON INPUT CHAR
    #- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 

maincase1:  # TEST FOR NEWLINE

    li  $t2, 0x0a             #    if (c == '\n') 
    beq $s3, $t2, print_stack #        break ;

maincase2:  # TEST FOR ENTER NEW NUMBER

    li  $t2, 'e'              #    if (c == 'e')
    bne $s3, $t2, maincase3
                              #    {
    move $a0, $zero           #       push(0) ;
    jal push
    j maincases_end           #    } else


maincase3:      
    # TEST FOR DIGIT
                              # if ('0' <= c && c <= '9') 

    li   $t1, '0'             # // $t1 = '0'
    slt  $t2, $s3, $t1        # // $t2 = c < '0'
    bnez $t2, maincase4       # // Skip case if c < '0'

    li   $t2, '9'             # // $t2 = '9'
    slt  $t3, $t2, $s3        # // $t3 = '9' < c
    bnez $t3, maincase4       # // Skip case if '9' < c
                              # {

                            #    push (10 * pop() + (c - '0'));

    sub $s4, $s3, $t1       #    // $s4 = c - '0'
    jal pop                 #    // $v0 = pop()
    sll $t2, $v0, 1         
    sll $t3, $v0, 3
    add $t3, $t2, $t3       #    // $t3 = 10 * $v0
    add $t3, $t3, $s4       #    // $t3 = $t3 + (c - '0')
    move $a0, $t3
    jal push                #    // push $t3

                            # }
    j maincases_end         # else

maincase4:  # TEST FOR NEGATE

    li  $t2, 'n'            # if (c == 'n') 
    bne $s3, $t2, maincase5
                            # {
                            #    push(-pop());
    jal pop
    sub $a0, $zero, $v0
    jal push
    j maincases_end         # } else 

maincase5:  # TEST FOR + OPERATION

    li  $t2, '+'            # if (c == '+')
    bne $s3, $t2, maincase6
                            # {
                            #    push(pop() + pop());
    jal pop                 #    // $s4 = pop()
    move $s4, $v0
    jal pop                 #    // $v0 = pop()
    add  $a0, $s4, $v0      #    // $a0 = pop() + pop()
    jal push
    j maincases_end         # } else 

maincase6:  # TEST FOR - OPERATION

    li  $t2, '-'            # if (c == '-')
    bne $s3, $t2, maincase7
                            # {
                            #    int arg2 = pop(); // 2nd arg for -
    jal pop                 #    // $s4 = pop()  
    move $s4, $v0
                            #    int arg1 = pop(); // 1st arg for -
    jal pop                 #    // $v0 = pop()

                            #    push(arg1 - arg2);
    sub  $a0, $v0, $s4      #    // $a0 = arg1 - arg2
    jal push                #    // push($a0)

    j maincases_end         # } else 

maincase7:  # TEST FOR * OPERATION

    li  $t2, '*'            # if (c == '*')
    bne $s3, $t2, maincases_end
                            # {
                            #    push(pop() * pop());
    jal pop                 #    // $s4 = pop()
    move $s4, $v0
    jal pop                 #    // $v0 = pop()
    mul  $a0, $s4, $v0      #    // $a0 = pop() * pop()
    jal push                #    // push($a0)
                            # }        

maincases_end:
    j mainloop

    #- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
    # PRINT_STACK 
    #- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 

print_stack:
    li    $v0, 4            #    print_string("\n") ;
    la    $a0, newline
    syscall

                            #    // This test for the stack being
                            #    // empty was not required in the     submitted
                            #    // solutions.  Indeed the print code
                            #    // in the else case below functions
                            #    // correctly also when stack == stackp.

    bne  $s1, $s0, print1   #    if (stack == stackp) {

    # Uncomment following code to print a message on the stack being empty
    # 
    # li $v0, 4               #       print_string("EMPTY\n")
    # la $a0, empty
    # syscall

    j print_end
print1:                         #    else {
                            #       int * pp; // Use $s4 for pp (print ptr)
    move $s4, $s1           #       pp = stack ;

print2: beq  $s4, $s0, print_end#       while (pp != stackp) {

    li   $v0, 1             #          print_int(pp - stack) ;
    sub  $a0, $s4, $s1      # 
    srl  $a0, $a0, 2        # 
    syscall

    li    $v0, 4            #          print_string(": ") ;
    la    $a0, colonsp
    syscall

    li    $v0, 1            #          print_int(*pp) ;
    lw    $a0, 0($s4)
    syscall

    li    $v0, 4            #          print_string("\n") ;
    la    $a0, newline
    syscall

    add $s4, $s4, 4         #          pp++ ;
    j print2
                            #       }
                            #    }
print_end:

    li $v0, 10      # exit()#    exit() ;
    syscall

    #----------------------------------------------------------------
    # END OF CODE
    #----------------------------------------------------------------
#======================================================
#反向波兰符号计算器
# ===================================================================
#MIPS中的RPN计算器
#
#Inf2C CS课程作业1。任务B
#解决方案
#
#保罗·杰克逊
#2012年10月10日
#==================================================================
#数据段
#==================================================================
.数据
#//内存中的全局变量
#int堆栈[堆栈大小];
.align 2#//确保堆栈数组从字边界开始
堆栈:。空格20#//为堆栈分配堆栈大小*4字节字
#//其中STACK_SIZE=5。
栈尾:
#//字符串常量
提示:.asciiz“>”#char*prompt=“>”;
新行:
.asciiz“\n”#char*newline=“\n”;
空:#char*empty=“(空)\n”//Stack空消息
.asciiz“(空)\n”
科隆普:
.asciiz:“#char*colonsp=”:“//用于堆栈打印格式
#==================================================================
#文本段
#==================================================================
.文本
#//注册用法。
# //
#int*stackp;//$s0。堆栈指针
#int*stack;//$s1&堆栈[0]-堆栈的起始地址
#int*堆栈_end;//$s2&堆栈[堆栈大小]-之后的第一个地址
#//堆栈末尾
#整数c/$s3。输入字符(强制为int)
#int s4/$s4在函数调用之间保留的临时变量
#int s5/$s5在函数调用之间保留的临时变量
#------------------------------------------------------------------
#推送功能
#------------------------------------------------------------------
#无效推送(int i)
#我的货币是a0美元
推:#{
#if(堆栈P<堆栈U端)
slt$t1、$s0、$s2#/$t1=stackp”)
la$a0,提示
系统调用
#- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
#读循环
#- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
主循环:#while(1){
li$v0,12#c=read_char()
系统调用
移动$s3,$v0
#- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
#输入字符上的CASE开关
#- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
主要案例1:#新线测试
li$t2,0x0a#if(c=='\n')
beq$s3,$t2,打印堆栈中断;
maincase2:#输入新号码的测试
li$t2,‘e’#如果(c==‘e’)
bne$s3,$t2,主要案例3
#    {
移动$a0,$0#推(0);
日航推
j主要案例(完)其他
主要案例3:
#数字测试

#如果('0'),可能对您没有帮助,但此程序在其状态下无法正常工作。如果我们希望使用反向波兰符号,则代码不正确。但是,我仍将尝试回答

Stack_end基本上是一个空地址,它里面没有任何东西,程序员希望使用它来找到堆栈末尾后的第一个位置

每次遇到一个数字,我们都会按(0)。如果你用高级语言思考,这是没有意义的,但在mips中,我们会移动$a0,$0,这意味着我们为下一个输入的数字让路。所以我们基本上是“移位”堆栈中向上的元素和第一个位置的新0元素将被我们的输入替换

最后,行推送(10*pop()+(c-‘0’)仅在汇编中才有意义
Step 1: In ASCII 51(3) - 48 = 3;
Step 2: x * 10 =0
Step 3: x + 3 = 3
Step 4: In ASCII 50(2) -48 = 2
Step 5: x *10 = 30
Step 6: x + 2 = 32