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

标签 c byte branch mips bit

我正在尝试编写一个程序来检查整数中的 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 返回到分支语句之后。 jr $ra 似乎让我返回到 chk_zerosadd 中的主函数。

最佳答案

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

    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

关于c - MIPS 中 For 循环分支后跳转到地址,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28955790/

相关文章:

c - Linux TCP 服务器,每 X 秒向几个客户端发送 RAW 数据

java - 有没有办法在java中将字节转换为 boolean 数组?

git branch 回滚到之前的提交

git - 使用 git-svn 创建一个新的 svn 分支

c - token 表;从 main.c 中的表获取信息?

c - 错误地址 C(命令行解释器)

C - 段错误(核心已转储)

c# - 使用 ASCII 字符编码在 C# 中将字符串转换为 byte[] 数组的最快方法(性能方面)

java - 在 Java 中将字节字符串转换为字母数字字符数组?

Git:为什么 git 在我还没有 pull 更新时说 "your branch is up to date with origin/main"?