Assembly MIPS程序集$ra值错误

Assembly MIPS程序集$ra值错误,assembly,return,mips,mars-simulator,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 sysca

我有这个程序来计算两个数字的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


我正在使用火星模拟器,如果我降低运行速度,这个错误会发生在包含jr$ra调用的线路上。非常感谢您的帮助。

问题是,如果GCD操作数的顺序已经正确,您将使用
beq
跳转到
GCD
,这不会设置
$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

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