0

我是汇编语言的新手,我遇到了一个奇怪的错误。该程序应该显示用户输入的整数的 4 个最低有效位。它适用于大于 8 的数字,但对于小于或等于 8 的数字,它会输出应该在的数字。对于 8,它输出 8000 而不是 1000,对于 5,它输出 0401。我不明白为什么,谁能帮忙?

        .data
inPrompt:   .asciiz "Enter an integer: "
outLab:     .asciiz "Least significant 4 bits of int entered are "
############################ code segment ################################
        .text
        .globl main
main:
        li $v0, 4
        la $a0, inPrompt        
        syscall                   # print input prompt

        li $v0, 5
        syscall                   # read input integer

        move $t0, $v0

        li $v0, 4
        la $a0, outLab        
        syscall

        li $v0, 1

        andi $a0, $t0, 8               
                syscall

        andi $a0, $t0, 4             
                syscall

        andi $a0, $t0, 2             
                syscall

        andi $a0, $t0, 1        
                syscall
          ##########################################################

                li $v0, 10               # exit
                syscall
4

1 回答 1

0

问题是您正在有效地计算和打印数字的加法分解(以 2 的幂为因子)而不是其位。

简单地说,例如对于“第 4 位”
  andi $a0, $t0, 4
,将导致存储在寄存器中A0......
- ..4如果寄存器中的值T0具有 4 的附加因子(例如 4、5、6、7、12、13 等.)

- ... 如果 in 的值T0不具有 4 的附加因子(例如 0、1、2、3、8、9、10 等),则值为 0。

这解释了为什么5你得到 0401 since5 is 4 + 1或更准确地说,5 is 0 * 8 + 4 + 0 * 2 + 1

您需要做的是以下两件事之一:

  • 测试andi运算结果的结果是否为非零,在这种情况下,在调用 syscall 或之前将 1 加载到 $a0 中
  • [bitwise] 将运算结果移动andi相应的位数(测试“8 bit”时移动3次,测试“4 bit”时移动2次,测试“2 bit”时移动一次)

第一个建议将导致类似于以下内容,以代替“andi + syscall”组:

            andi $a0, $t0, 4
            blez $a0, outBit4  # bit is zero output integer value 0
            li $a0, 1          # bit is one  ouptut integer value 1 (repl 4 by 1)
  outBit4:  syscall

编辑
将程序保持在 16 LoC 以下... (顺便说一句,此要求和其他提示表明homework,因此我将提供一般想法而不是给出代码)
有几种方法可以缩短代码,但 16 LoC考虑到设置使用了 9 行,要求有点困难:提示用户输入,获取输入并保存它,并输出答案的开始......

最常见的方法是使用一个(或多个嵌套的)循环。在这种情况下,一个循环就足够了,基本上您需要重复 4 次几乎相同的事情,因此以添加一些 LoC 来管理循环本身(即增加参数和检测循环结束条件)为代价,您可以编写以参数化方式处理单个工作单元的片段,并在循环中包含此逻辑。

一个稍微相关的方法是使用子例程,其中重复的逻辑写在一个子例程中,然后可以多次调用,传递不同的参数来实现参数化的行为。

我提到了上面的内容,因为它们在汇编语言中非常常用,并且确实在大型编程中使用。然而,以目前的“基于andi”的逻辑,恐怕这两种方法都不会将事情带入16 LoC 以下。您可能需要使用循环结构位移逻辑。

于 2013-03-04T05:14:01.760 回答