n choose k in MIPS Assembly

huangapple go评论59阅读模式
英文:

n choose k in MIPS Assembly

问题

以下是您提供的代码的中文翻译:

.text
    addi	$v0, $zero, 5
    syscall
    add	$a0, $v0, $zero  
    
    addi	$v0, $zero, 5
    syscall
    add	$a1, $v0, $zero  # 调用选择函数
    jal	choose

    add	$a0, $v0, $zero  # 打印结果
    addi	$v0, $zero, 1
    syscall

    addi	$v0, $zero, 10   # 退出程序
    syscall

choose:
    addi 	$sp, $sp, -16    
    sw 	$ra, 0($sp)        # 将返回地址保存在堆栈上
    sw 	$s0, 4($sp)        # 将s0保存在堆栈上
    sw 	$a0, 8($sp)        # 将n保存在堆栈上
    sw 	$a1, 12($sp)       # 将k保存在堆栈上

    slt 	$t0, $a0, $a1     # 检查是否n < k
    beq 	$t0, $1, choose_end
    beq 	$a0, $0, choose_one   # 检查是否n == 0或k == 0
    beq 	$a1, $0, choose_one

    addi 	$a0, $a0, -1     # 计算choose(n-1, k-1)
    addi 	$a1, $a1, -1
    jal 	choose
    move 	$s0, $v0

    addi 	$a0, $a0, 1     # 计算choose(n-1, k)
    jal 	choose
    add 	$v0, $s0, $v0     # 将val1和val2相加

    j 	choose_end

choose_one:
    li 	$v0, 1             # 返回1
    j 	choose_end

choose_end:
    lw 	$ra, 0($sp)        # 恢复返回地址
    lw 	$s0, 4($sp)        # 恢复s0
    addi 	$sp, $sp, 16     # 从堆栈中分配空间
    jr 	$ra                # 返回给调用者

关于您的代码问题,您提到输入2和3,结果是4,这可能是因为代码的问题,但不足以确定问题的根本原因。要诊断问题,您需要仔细检查代码的逻辑,确保它正确地执行所需的操作。可能有一些问题在选择函数(choose)中,您可以检查函数的递归和返回值以确保正确性。如果有更多信息或特定的问题,欢迎提出以获取更多帮助。

英文:
    .text
	    addi	$v0, $zero, 5
	    syscall
	    add	$a0, $v0, $zero  
	
	    addi	$v0, $zero, 5
	    syscall
	    add	$a1, $v0, $zero  #call choose function
	    jal	choose

	    add	$a0, $v0, $zero  #print result
	    addi	$v0, $zero, 1
	    syscall

	    addi	$v0, $zero, 10   #exit program
	    syscall

choose:
    	addi 	$sp, $sp, -16    
    	sw 	$ra, 0($sp)        # save the return address on the stack
    	sw 	$s0, 4($sp)        # save s0 on the stack
    	sw 	$a0, 8($sp)        # save n on the stack
    	sw 	$a1, 12($sp)       # save k on the stack

    	slt 	$t0, $a0, $a1     # check if n &lt; k
    	beq 	$t0, $1, choose_end
    	beq 	$a0, $0, choose_one   # check if n == 0 or k == 0
    	beq 	$a1, $0, choose_one

    	addi 	$a0, $a0, -1     # calculate choose(n-1, k-1)
    	addi 	$a1, $a1, -1
    	jal 	choose
    	move 	$s0, $v0

    	addi 	$a0, $a0, 1     # calculate choose(n-1, k)
    	jal 	choose
    	add 	$v0, $s0, $v0     # add val1 and val2

    	j 	choose_end

choose_one:
    	li 	$v0, 1             # return 1
    	j 	choose_end

choose_end:
    	lw 	$ra, 0($sp)        # restore the return address
    	lw 	$s0, 4($sp)        # restore s0
    	addi 	$sp, $sp, 16     # deallocate space from stack
    	jr 	$ra                # return to caller

Idk what's wrong with this code

I enter 2 and 3 and the result is 4

答案1

得分: 1

  • beq $t0, $1, choose_end并不是将$t0与一个常数值1进行比较。这条指令是将$t0与寄存器编号为1的寄存器比较,而这个寄存器是$at,它是汇编器保留的寄存器。你应该使用bne $t0, $0, choose_end来检查比较结果。

  • 你将nk保存到堆栈中,但却没有恢复它们。在第一次递归函数调用之后,应该添加一些代码来恢复它们。

  • 你忘记设置返回值,应该为n < k的情况设置返回值为0

修复后的代码:

choose:
        addi    $sp, $sp, -16
        sw  $ra, 0($sp)        # 将返回地址保存在堆栈中
        sw  $s0, 4($sp)        # 将s0保存在堆栈中
        sw  $a0, 8($sp)        # 将n保存在堆栈中
        sw  $a1, 12($sp)       # 将k保存在堆栈中

        slt     $t0, $a0, $a1     # 检查是否n < k
        # 使用正确的比较,然后设置返回值
        #beq     $t0, $1, choose_end
        bne     $t0, $0, choose_zero
        beq     $a0, $0, choose_one   # 检查是否n == 0或k == 0
        beq     $a1, $0, choose_one

        addi    $a0, $a0, -1     # 计算choose(n-1, k-1)
        addi    $a1, $a1, -1
        jal     choose
        move    $s0, $v0

        # 恢复n和k
        lw $a0, 8($sp)
        lw $a1, 12($sp)
        # 下一次调用应该使用n-1,而不是n+1
        #addi    $a0, $a0, 1     # 计算choose(n-1, k)
        addi    $a0, $a0, -1     # 计算choose(n-1, k)
        jal     choose
        add     $v0, $s0, $v0     # 加上val1和val2

        j   choose_end

choose_one:
        li  $v0, 1             # 返回1
        j   choose_end

        # 为n < k的情况设置返回值
choose_zero:
        li $v0, 0

choose_end:
        lw  $ra, 0($sp)        # 恢复返回地址
        lw  $s0, 4($sp)        # 恢复s0
        addi    $sp, $sp, 16     # 从堆栈中释放空间
        jr  $ra                # 返回给调用者
英文:
  • beq $t0, $1, choose_end is not comparing $t0 to a constant value 1. This instruction is comparing $t0 with register No.1, which is a register $at, which is reserved for an assembler. You should use bne $t0, $0, choose_end instead to check the comparision result.
  • You saved n and k to the stack, but never restored them. Some code to restore them should be added after the first recursive function call.
  • You forgot to set the return value, which should be 0, for the n &lt; k case.

Fixed code:

choose:
        addi    $sp, $sp, -16
        sw  $ra, 0($sp)        # save the return address on the stack
        sw  $s0, 4($sp)        # save s0 on the stack
        sw  $a0, 8($sp)        # save n on the stack
        sw  $a1, 12($sp)       # save k on the stack

        slt     $t0, $a0, $a1     # check if n &lt; k
        # use proper comparision, and go to setting the return value
        #beq     $t0, $1, choose_end
        bne     $t0, $0, choose_zero
        beq     $a0, $0, choose_one   # check if n == 0 or k == 0
        beq     $a1, $0, choose_one

        addi    $a0, $a0, -1     # calculate choose(n-1, k-1)
        addi    $a1, $a1, -1
        jal     choose
        move    $s0, $v0

        # restore n and k
        lw $a0, 8($sp)
        lw $a1, 12($sp)
        # n-1, not n+1, should be used for the next call
        #addi    $a0, $a0, 1     # calculate choose(n-1, k)
        addi    $a0, $a0, -1     # calculate choose(n-1, k)
        jal     choose
        add     $v0, $s0, $v0     # add val1 and val2

        j   choose_end

choose_one:
        li  $v0, 1             # return 1
        j   choose_end

        # set the return value for n &lt; k case
choose_zero:
        li $v0, 0

choose_end:
        lw  $ra, 0($sp)        # restore the return address
        lw  $s0, 4($sp)        # restore s0
        addi    $sp, $sp, 16     # deallocate space from stack
        jr  $ra                # return to caller

huangapple
  • 本文由 发表于 2023年2月27日 11:31:13
  • 转载请务必保留本文链接:https://go.coder-hub.com/75576560.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定