汇编语言奇怪的错误

时间:2013-03-04 04:49:11

标签: assembly mips

我是汇编语言的新手,我遇到了一个奇怪的错误。程序应该显示用户输入的整数的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

1 个答案:

答案 0 :(得分:0)

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

简单地说,例如“bit 4”
 andi $a0, $t0, 4
将导致存储在寄存器A0 ...中    - 如果寄存器4中的值的加法因子为4(例如4,5,6,7,12,13等),则值为T0
  - 如果T0中的值没有加法因子4(例如0,1,2,3,8,9,10等),则值为0。

这解释了为什么50401获得5 is 4 + 1或更准确地说5 is 0 * 8 + 4 + 0 * 2 + 1

你需要做的是 两件事之一:

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

第一个建议会导致类似下面的内容,而不是'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所以我将提供一般性的想法,而不是给出代码)
有两种方法可以缩短代码,但考虑到9行使用设置:16 LoC要求有点困难:提示用户输入,获取输入并保存,并输出答案的开头...... < / p>

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

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

我提到了上面的内容,因为它们在汇编语言中非常常用,实际上也是一般的编程。然而,由于目前的'基于andi'的逻辑,这些方法都不会使事情低于16 LoC,我担心。您可能需要使用循环结构一个位移逻辑。