Thứ Hai, 5 tháng 3, 2012

Chương trình tính giá trị biểu thức bằng hợp ngữ MIPS


Xây dựng chương trình MIPS sau (không bắt buộc dùng thủ tục/hàm):
Nhập vào chuỗi biểu thức gồm có các toán tử sau: + – * / (_), và tính kết quả của biểu thức đó.
Ví dụ: 12*3+24/(9-3)-90

Ghi chú:
+ Độ ưu tiên của toán tử: 1: (_) ; 2: * / ; 3: + -
+ Các toán hạng là số nguyên được giới hạn trong đoạn [0,999]
+ Tìm hiểu stack và thuật toán balan ngược (trong cấu trúc dữ liệu)
+ Kết quả của biểu thức: số nguyên hoặc số thực (chỉ cần chọn 1 trong 2) hoặc số thực (chỉ cần chọn 1 trong 2)
Đây là bài làm của tôi:
# $s1:  expression string
# $sp, $t0: stack
# $s0, $t1: queue

.data
  text_1: .asciiz "Nhap bieu thuc: "
  text_2: .asciiz "Gia tri bieu thuc: "
  text_3: .asciiz "Bieu thuc khong dung!"
.text

main:
  move $t0, $sp
  addi $s0, $sp, -102400
  move $t1, $s0
  addi $s1, $s0, -102400

  li $v0, 4 #print string
  la $a0, text_1
  syscall

  addi $s1, $s1, -1024
  move $a0, $s1
  li $v0, 8 #read string
  li $a1, 1024
  syscall

  Infix2Postfix:
  lbu $t2, 0($s1)
  beq $t2, 10, end_Infix2Postfix # if s[0]=='n' goto end_Infix2Postfix

  beq $t2, '(',open
  beq $t2, ')',close
  beq $t2, '+',operator
  beq $t2, '-',operator
  beq $t2, '*',operator
  beq $t2, '/',operator
  move $a0, $t2
  jal Is_number
  beq $v0, 1, operand

  addi $s1, $s1, 1 # next character
  j Infix2Postfix

  open:
  li $a0, 0
  li $a1, 0
  jal Push_stack
  addi $s1, $s1, 1 # next character
  j Infix2Postfix

  close:
  jal Is_Empty_stack
  beq $v0, 1, Expression_Error

  jal Pop_stack
  beq $v0, $zero, end_close
  move $a0, $v0
  move $a1, $v1
  jal Push_queue
  j close

  end_close:
  addi $s1, $s1, 1 # next character
  j Infix2Postfix

  operator:

  beq $t2, '+',o1
  beq $t2, '-',o1
  beq $t2, '*',o2
  beq $t2, '/',o2

  o1:
  li $t3, 1
  j while_o
  o2:
  li $t3, 2

  while_o:
  jal Is_Empty_stack
  beq $v0, 1, end_while_o

  jal Top_stack
  slt $t4, $v0, $t3
  beq $t4, 1, end_while_o

  jal Pop_stack
  move $a0, $v0
  move $a1, $v1
  jal Push_queue

  end_while_o:
  move $a0, $t3
  move $a1, $t2
  jal Push_stack
  addi $s1, $s1, 1 # next character
  j Infix2Postfix

  operand:
  sub $t3, $t2, '0'
  while_number:
  lbu $t2, 1($s1)
  move $a0, $t2
  jal Is_number
  beq $v0, 0, end_while_number
  mul $t3, $t3, 10
  sub $t2, $t2, '0'
  add $t3, $t3, $t2
  addi $s1, $s1, 1
  j while_number
  end_while_number:
  li $a0, 3
  move $a1, $t3
  jal Push_queue
  addi $s1, $s1, 1 # next character
  j Infix2Postfix

  end_Infix2Postfix:

  while_not_Empty_stack:
  jal Is_Empty_stack
  beq $v0, 1, end_while_not_Empty_stack
  jal Pop_stack
  move $a0, $v0
  move $a1, $v1
  jal Push_queue
  j while_not_Empty_stack
  end_while_not_Empty_stack:

  while_not_Empty_queue:
  jal Is_Empty_queue
  beq $v0, 1, end_while_not_Empty_queue
  jal Pop_queue
  beq $v0, 3, _operand

  move $a2, $v1
  jal Pop_stack
  bne $v0, 3, Expression_Error
  move $a1, $v1
  jal Pop_stack
  bne $v0, 3, Expression_Error
  move $a0, $v1
  jal calculate
  li $a0, 3
  move $a1, $v0
  jal Push_stack

  j while_not_Empty_queue
  _operand:
  move $a0, $v0
  move $a1, $v1
  jal Push_stack
  j while_not_Empty_queue

  end_while_not_Empty_queue:

  li $v0, 4 #print string
  la $a0, text_2
  syscall

  jal Pop_stack
  move $a0, $v1
  li $v0, 1
  syscall

  end_program:
  li $v0, 10 #exit
  syscall

Expression_Error:
  li $v0, 4 #print string
  la $a0, text_3
  syscall
  j end_program

Is_number:
  beq $a0, '0',_number
  beq $a0, '1',_number
  beq $a0, '2',_number
  beq $a0, '3',_number
  beq $a0, '4',_number
  beq $a0, '5',_number
  beq $a0, '6',_number
  beq $a0, '7',_number
  beq $a0, '8',_number
  beq $a0, '9',_number

  li $v0, 0
  jr $ra
  _number:
  li $v0, 1
  jr $ra

calculate:
  beq $a2, '+', _add
  beq $a2, '-', _sub
  beq $a2, '*', _mul

  div $a0, $a1
  mflo $v0
  jr $ra

  _add:
  add $v0, $a0, $a1
  jr $ra

  _sub:
  sub $v0, $a0, $a1
  jr $ra

  _mul:
  mul $v0, $a0, $a1
  jr $ra

Push_stack:
  addi $t0, $t0, -8
  sw $a0, 0($t0)  #save type of token
  sw $a1, 4($t0)  #save value of token
  jr $ra

Push_queue:
  addi $s0, $s0, -8
  sw $a0, 0($s0)  #save type of token
  sw $a1, 4($s0)  #save value of token
  jr $ra

Pop_stack:
  lw $v0, 0($t0)
  lw $v1, 4($t0)
  addi $t0, $t0, 8
  jr $ra

Top_stack:
  lw $v0, 0($t0)
  lw $v1, 4($t0)
  jr $ra

Pop_queue:
  lw $v0, -8($t1)
  lw $v1, -4($t1)
  addi $t1, $t1, -8
  jr $ra

Is_Empty_stack:
  beq $sp, $t0, Empty_stack
  li $v0, 0
  jr $ra
  Empty_stack:
  li $v0, 1
  jr $ra

Is_Empty_queue:
  beq $s0, $t1, Empty_queue
  li $v0, 0
  jr $ra
  Empty_queue:
  li $v0, 1
  jr $ra
Share this post
  • Share to Facebook
  • Share to Twitter
  • Share to Google+
  • Share to Stumble Upon
  • Share to Evernote
  • Share to Blogger
  • Share to Email
  • Share to Yahoo Messenger
  • More...

0 nhận xét

:) :-) :)) =)) :( :-( :(( :d :-d @-) :p :o :>) (o) [-( :-? (p) :-s (m) 8-) :-t :-b b-( :-# =p~ :-$ (b) (f) x-) (k) (h) (c) cheer

 
© Download do an khoa luan tai lieu
Designed by BlogThietKe Cooperated with Duy Pham
Released under Creative Commons 3.0 CC BY-NC 3.0
Posts RSSComments RSS
Back to top