我是汇编语言的新手,我遇到了一个奇怪的错误。程序应该显示用户输入的整数的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
答案 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。
这解释了为什么5
从0401
获得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
修改强>: 最常见的方法是使用一个(或几个嵌套的)循环。在这种情况下,单个循环就足够了,基本上你需要重复4次几乎相同的事情,所以代价是添加一些LoC来管理循环本身(即增加参数和检测循环结束条件),你可以写一个以参数化方式处理单个工作单元的片段,并在循环中具有此逻辑。 一种稍微相关的方法是使用子程序,从而在子程序中写入重复的逻辑,然后可以多次调用,传递不同的参数来实现参数化行为。 我提到了上面的内容,因为它们在汇编语言中非常常用,实际上也是一般的编程。然而,由于目前的'基于andi'的逻辑,这些方法都不会使事情低于16 LoC,我担心。您可能需要使用循环结构和一个位移逻辑。
保持程序低于16 LoC ... (顺便说一句,此要求和其他提示表明homework
所以我将提供一般性的想法,而不是给出代码)
有两种方法可以缩短代码,但考虑到9行使用设置:16 LoC要求有点困难:提示用户输入,获取输入并保存,并输出答案的开头...... < / p>