我试图将基数为10的输入转换为二进制,并试图将其存储在input_buffer中,然后打印出input_buffer。当我尝试它不打印任何东西,如果它是空的参考这里是我有:
.data
ask_input: .asciiz "Enter a number (0-255): "
binary: .asciiz "\nThe number in base 2 is: "
input_buffer: .space 10
.text
.globl main
main:
# Ask for input
li $v0, 4
la $a0, ask_input
syscall
# Assign input
li $v0, 5
syscall
move $s0, $v0 # Integer is stored in $s0
# Setup
li $t0, 2 # For dividing by 2
li $t1, 0 # For holding binary
li $t2, 8 # Assume 8-bit binary response
# Initialize the input_buffer with null bytes
li $t3, 0 # Null byte
li $t4, 10 # Number of bytes to initialize
la $t5, input_buffer # Address of input_buffer
initialize_buffer:
sb $t3, ($t5) # Store a null byte
addi $t5, $t5, 1 # Move to the next byte
addi $t4, $t4, -1 # Decrement the byte count
bnez $t4, initialize_buffer # Continue until all bytes are null
convert_loop:
# Continue the loop until $s0 is not equal to 0
bnez $s0, continue_conversion
# If $s0 is 0, jump to printing the binary
j print_bin
continue_conversion:
# Use 'and' with 1 for the least significant digit
andi $t3, $s0, 1
# Convert the least significant digit to '0' or '1'
addi $t3, $t3, '0'
# Store the ASCII character in input_buffer
sb $t3, input_buffer($t2)
# Right shift for division by 2
srl $s0, $s0, 1
# Decrement the counter
addi $t2, $t2, -1
# Continue the loop
j convert_loop
print_bin:
# Print the output message
li $v0, 4
la $a0, binary
syscall
# Print the binary representation stored in input_buffer
li $v0, 4
la $a0, input_buffer
syscall
# Exit
li $v0, 10
syscall
1条答案
按热度按时间qyswt5oh1#
您将数字反向存储到缓冲区中-从缓冲区的末尾开始反向工作。当输入值变为0时,转换循环停止。因此,对于像3这样的输入值,它存储'1',然后'1',然后停止。缓冲区看起来像这样:
然后从缓冲区的开头开始打印,缓冲区为null,因此当然不会打印任何内容。用于打印字符串的系统调用#4在它看到的第一个null处停止,即它打印一个以null结尾的字符串。如果系统调用忽略null,直到找到合适的字符来打印,然后荣誉null结束字符串,这将是愚蠢的,不是吗?原因是空字符串是一个有效的字符串,一个零长度的字符串,系统(系统调用,printf等)处理这一点非常正常。
要解决这个问题,你可以做以下 * 一 *(提示其中一个比其他的更容易):
这将打印前导空格后跟11,或者,
使用
la $a0, input_buffer+1($t2)
,或者,如果你做这个额外的复制,真的没有理由在转换中向后工作,因为可以向后复制。可能想使用一个单独的第二个缓冲区,但可以只使用一个缓冲区,如果小心边缘。但由于复印的原因,效率较低。
如果你把数据存储到缓冲区中,就没有必要用空值初始化它。如果您的算法精确地使用缓冲区,它将覆盖那里的任何旧值,即使程序在循环中运行用户输入,转换和输出。
但由于它不是在循环中运行,因此null初始化已经在程序加载到内存中时完成,因为.space指令指示了这一点。当然,这只会在节目开始时进行一次。(虽然正如我所说的,如果你正确使用缓冲区,任何新的输出都会覆盖旧的输出,从而避免了空字节的初始化。)
在以下
这应该使用
addiu
而不是addi
,因为这是指针运算,而指针运算是无符号整数运算。使用addi
有符号溢出异常的风险,这不仅不相关,而且对于无符号算术是错误的。但是,考虑到数据的起始地址和范围,这个问题不会出现。如果你的程序正在使用堆,并且使用了很多堆,这个逻辑错误可能会显示出来(作为一个不需要的异常,停止程序)。