assembly MIPS/ MARS:二进制打印

pb3skfrl  于 2023-10-19  发布在  其他
关注(0)|答案(1)|浏览(88)

该程序在开始时包含主代码,用于调用一个名为print_binary的子例程,其中包含三个测试编号。你的任务是编写print_binary。print_binary的结尾已经写好了:它打印一个新行并返回:
00000000000000000000000000000011
11111111111111111111111111111111
11001010111111101111000000001101
到目前为止,我的输出是:
00000000000000000000000000000000
10000000000000000000000000000000
10000000000000000000000000000000
需要注意的是,我不允许更改main:结尾:
我很感激任何能帮上忙的人,
谢谢你,

.text
main:
    li  $a0, 2
    jal print_binary
    li  $a0, -1
    jal print_binary
    li  $a0, 0xcafef00d
    jal print_binary

    li  $v0, 10             # exit
    syscall

# On entry, a0 = number to print in binary
print_binary:
    li $t1, 32               # Initialize a counter for the bit position (32 bits for unsigned)

loop:
    beqz $t1, end           # Exit the loop if all bits have been processed

    srl $t2, $a0, 31        # Get the most significant bit of the number
    andi $t2, $t2, 1        # Mask the least significant bit
    addi $t2, $t2, 48       # Convert the bit value to ASCII ('0' or '1')

    li $v0, 11              # syscall to print one char
    move $a0, $t2           # Load the bit value into $a0
    syscall

    sll $a0, $a0, 1         # Shift the original number to the left by 1 bit
    addiu $t1, $t1, -1      # Decrement the counter
    j loop

end:
    li $v0, 11              # syscall to print one char
    li $a0, 10              # Load newline character into $a0 ('\n')
    syscall
    jr $ra
tf7tbtn2

tf7tbtn21#

问题是,您期望$a0保存它的值,而您的代码打印一个字符时会将其删除。为了使系统调用打印字符,$a0必须重新使用,并且其中的原始值丢失。

li $v0, 11              # syscall to print one char
move $a0, $t2           # Load the bit value into $a0  <<--- overwrites $a0
syscall

你必须找到一种方法来保存$a0中的值。有几种选择。

  • 转移(复制/移动)到另一个寄存器。 syscall是友好的,它保留了除了返回值之外的所有寄存器,如果系统调用提供了一个的话-所以你可以在函数的开始将值移动到$t3,然后从那里使用它,而不是从$a0
  • 使用一些堆栈空间--如果你调用另一个函数而不是使用syscall,这种方法是必要的。

有两种方法可以使用一些堆栈空间来保留此值:

  • 简单地将$a0值“推送”(在MIPS意义上)到堆栈,并在循环期间根据需要从堆栈内存中重新加载它,或者,
  • 将一个$s寄存器“压入”堆栈,并将$a0复制到该$s寄存器,然后从那里开始使用。

任何一种堆栈空间方法都需要您分配堆栈空间,并在返回给调用方之前解除分配。
作为一个旁注,您可以观察到,在单步调试过程中,$a0被清除了以前的值。在调试汇编语言代码时,观察寄存器何时意外更改是很有用的,特别是因为系统调用和/或函数调用-尽管在这种情况下,是您自己的代码覆盖了原始参数(在设置系统调用时),而不是系统调用本身。

相关问题