MIPS 中 For 循环分支后跳转到地址

Jump to Address after Branching in For Loop in MIPS

我正在尝试编写一个程序来检查整数中的 16 位是 1 还是 0。我选择通过将一位右移 15 次并检查每次移位中的第一位是零还是非零来实现这一点。然后,如果第一位是 1,我递增一个整数。

我用 C 编写了一些代码,代表我的代码的非用户输入版本。

int j = 100;
int checker = 0;
int count = 0;
for (i=0; i<16; i++) {
  checker = j & 0x1;
  if (checker > 0)
    count++;
  j = (j >> 1);
}

我的 MIPS 代码:

  .data
    userprompt: .asciiz "Enter positive integer: "
    newline: .asciiz "\n"
  .text
  .globl main

main:   
  li  $v0, 4              # System call: Display string
  la  $a0, userprompt     # Load string userprompt for output
  syscall

  li  $v0, 5              # System call: Read integer
  syscall
  move $s0, $v0           # Store integer from v0 to s0

  move $s1, $s0           # s1 = s0
  li $t0, 0               # t0 = 0
  jal chk_zeros           # Run function: chk_zeroes

  li  $v0, 1              # System call: Read integer
  move  $a0, $t2         # Store integer from t2 to a0
  syscall
  li $v0, 10              # System call: quit
  syscall 

chk_zeros:
  bgt $t0, 15, exitchk    # t0 <= 15
  addi $t0, $t0, 1        # Add one to t0

  andi $t1, $s1, 0x1      # Check if first bit is non-zero, store in t1
  bgtz $t1, chk_zerosadd  # If t1 >= 0

  j chk_zeros

chk_zerosadd:
  addi $t2, $t2, 1        # Add one to t2
  jr $ra                  # Return to after the if statement (does not work!)

exitchk:
  jr $ra

我遇到的问题是在分支语句之后制作 chk_zerosadd return 。 jr $ra 似乎 return 我在 chk_zerosadd.

中的主要功能

bgtz不会将下一个PC地址放入return地址寄存器,所以jr $ra不会return到分支语句后的指令。您可以使用 bgtzal(如果大于零和 link 则分支),这将为您提供您正在寻找的行为,或者您可以重新安排您的代码,以便您通过添加分支,而不是像这样分支到它:

    andi $t1, $s1, 0x1      # Check if first bit is non-zero, store in t1
    beq $t1, chk_zerosskipadd  # Jump if $t1 is zerp
    addi $t2, $t2, 1        # Add one to t2
chk_zerosskipadd:
    # continue execution...

    srl $s1, $s1, 1         # j = (j >> 1);
    j chk_zeros