MIPS汇编$ ra值错误

时间:2015-10-28 20:00:16

标签: assembly return mips mars-simulator

我有这个程序来计算两个数字的GCD。我已执行该程序,它工作正常。但是我想稍微改一下以引入一个函数调用。以下是该计划。

# Declare main as a global function
.globl main

# All program code follows the .txt directive
.text

main:

# Print A integer user input request message
li  $v0, 4      # print_string syscall code = 4
la  $a0, msg1   # load msg1 address
syscall

# Get A input from user and save
li  $v0, 5      # read_int syscall code = 5
syscall
move    $t0, $v0    # syscall results returned in $v0, move $v0 to $t0

# Print B integer user input request message
li  $v0, 4      # print_string syscall code = 4
la  $a0, msg2   # load msg2 address
syscall

# Get B input from user and save
li  $v0, 5      # read_int syscall code = 5
syscall
move    $t1, $v0    # syscall results returned in $v0, move $v0 to $t1


# Verify both input values are positive integers greater than 0
PositiveCheck:
slti    $t7, $t0, 1 # Check if first input is less than 1
bne $t7, $zero, Negative
slti    $t7, $t1, 1 # Check if second input is less than 1
bne $t7, $zero, Negative


# Verify that A is larger than B, if not then swap the values
OrderCheck:
slt $t7, $t0, $t1   # Check if A is less than B
beq $t7, $zero, GCD
move    $t2, $t0    # Move A to temp value
move    $t0, $t1    # Make A = B
move    $t1, $t2    # Make B equal to temp value

jal GCD     # Call GCD function
j   Output      # Jump to Output

GCD:

 addi $sp, $sp, -12
 sw $t0, 0($sp)
 sw $t1, 4($sp)
 sw $ra, 8($sp)

CalcGCD:

# Start GCD Loop
beq $t1, $zero, Return  # Check if B value is 0
div $t0, $t1        # divide A by B
move    $t0, $t1        # Change A value to B
mfhi    $t1         # Change B value to A%B
j   CalcGCD         # Jump to GCD to repeat loop    

Return:

lw  $t0, 0($sp)
lw  $t1, 4($sp)
lw  $ra, 8($sp)
addi    $sp, $sp, 12
jr  $ra     # return value and exit function

Output:

# Output GCD of A & B
li  $v0, 4
la  $a0, msg3   # Print msg3
syscall
li  $v0, 1
move    $a0, $t0    # Output A value, which is now GCD
syscall

# Jump to exit
j   Exit

Negative:

# Output errormsg
li  $v0, 4      # print_string syscall code = 4
la  $a0, errormsg   # print errormsg
syscall

# Jump to exit
j   Exit        


Exit:

# Exit
li  $v0, 10     # exit call
syscall

# Start .data segment (data!)
.data

# Inital input message
msg1: .asciiz "Enter a positive integer for A: "
# Second input message
msg2: .asciiz "Enter a positive integer for B: "
# Final result message
msg3: .asciiz "The GCD is "
# Error message, called when user inputs negative integer
errormsg:   .asciiz "Error! You must enter a positive integer greater than   0. Please try again."

但是在执行时我收到以下错误。 错误:程序计数器值无效:0x00000000

我正在使用MARS模拟器,如果我减慢运行速度,则会在包含jr $ ra调用的行上发生此错误。非常感谢任何帮助。

1 个答案:

答案 0 :(得分:0)

问题在于,如果GCD操作数已经按照正确的顺序排列,那么您将使用GCD跳转到beq$ra不会设置OrderCheck: slt $t7, $t0, $t1 # Check if A is less than B beq $t7, $zero, orderOk move $t2, $t0 # Move A to temp value move $t0, $t1 # Make A = B move $t1, $t2 # Make B equal to temp value orderOk: jal GCD 。您可以通过将代码更改为以下内容来解决此问题:

%%var%%

你的代码中似乎还有一些其他问题,因为如果我输入25和15,我会得到25的结果,即使它应该是5.但这是一个单独的问题。