MIPS-0x004001e8处的运行时异常:提取地址未在字边界0x10010001上对齐

MIPS-0x004001e8处的运行时异常:提取地址未在字边界0x10010001上对齐,mips,Mips,我正在尝试在MIPS中实现puts。我有一个程序putchar,它将一个字符打印到屏幕上: .text putchar: lui $t0, 0xffff # base address of memory map XReady: lw $t1, 8($t0) #read from transmitter control register andi $t1, $t1, 0x1 # extract ready bit beqz $t1, XR

我正在尝试在MIPS中实现puts。我有一个程序putchar,它将一个字符打印到屏幕上:

    .text
putchar:
    lui $t0, 0xffff     # base address of memory map
XReady:
    lw $t1, 8($t0)      #read from transmitter control register
    andi $t1, $t1, 0x1  # extract ready bit
    beqz $t1, XReady       # if 1, store char ; else, loop
    sw $a0, 12($t0)     # send character to display
    jr $ra                 # return to place in program before function call
在我的主子程序中,我将$a0设置为要打印的字符串,然后调用puts:

我在用a标记的puts的第242行的字边界上得到一个错误获取地址未对齐*

    .text
puts:
    addi $sp, $sp, -24  # make room for 6 registers
    sw $ra, 20($sp)     # save $ra on the stack
    sw $s0, 16($sp)     # save $s0 on the stack
    sw, $s1, 12($sp)    # save $s1 on the stack
    sw, $s2, 8($sp)     # save $s2 on the stack
    sw, $s3, 4($sp)     # save $s3 on the stack
    sw, $s4, 0($sp)     # save $s4 on the stack

    move $s0, $a0       # copy parameter $a0 into $s0
    move $s1, $a1       # copy parameter $a0 into $s1
    move $s2, $a2       # copy parameter $a0 into $s2
    move $s3, $a3       # copy parameter $a0 into $s3
    move $s4, $zero     # s4 is a character counter. $s4 = 0
getsLoop:
    addi $t0, $zero, 0x00   # Put NULL ascii character inside $t0
    sll $t1, $s4, 2     # create buffer storing address ($t1 = $s1 * 4)
    add $t2, $s0, $t1   # register #t2 now holds buffer address
*   lw $t3, ($s0)       # load char into #t3
    beq $t3, $t0, exitPuts  # exit puts if the current character is the NULL character

    move $a0, $t3       # put the character to print inside $a0, accessible by putchar
    jal putchar     # print char using putchar
    addi $s0, $s0, 1    # character count += 1
    j getsLoop      # Loop to print next character
exitPuts:
    lw $s4, 0($sp)      # restore stack
    lw $s3, 4($sp)      # -
    lw $s2, 8($sp)      # -
    lw $s1, 12($sp)     # -
    lw $s0, 16($sp)     # -
    lw $ra, 20($sp)     # -
    addi $sp, $sp, 20   # pop from stack
    jr $ra          # return
我不知道为什么我会犯这个错误。。。$s0不是main中定义的数组地址吗?

使用lw时,加载整个单词4个字节,不要与自然语言中的单词混淆,并且该单词必须在单词边界上对齐。地址的两个最低有效位必须为0

ASCII字符通常使用每个字符一个字节来存储,因此您应该使用lbu指令来加载它们,而不是lw。

使用lw时,您将加载整个单词4个字节,以免与自然语言中的单词混淆,该字必须在字边界上对齐,地址的两个最低有效位必须为0


ASCII字符通常使用每个字符一个字节来存储,因此您应该使用lbu指令来加载它们,而不是lw。

谢谢,您的修改成功了。不过我很好奇。。。我的getchar正在读取内存中的一个字,并逐字寻址数组。你是说即使我在getchar中使用了sw,它也会将ASCII保存为一个字节吗?因为我还没有看到那段代码,所以我不知道。也许它将4个字符分组到一个寄存器中,然后使用sw存储它们。谢谢,您的修改成功了。不过我很好奇。。。我的getchar正在读取内存中的一个字,并逐字寻址数组。你是说即使我在getchar中使用了sw,它也会将ASCII保存为一个字节吗?因为我还没有看到那段代码,所以我不知道。可能它将4个字符分组到一个寄存器中,然后使用sw存储它们。
    .text
puts:
    addi $sp, $sp, -24  # make room for 6 registers
    sw $ra, 20($sp)     # save $ra on the stack
    sw $s0, 16($sp)     # save $s0 on the stack
    sw, $s1, 12($sp)    # save $s1 on the stack
    sw, $s2, 8($sp)     # save $s2 on the stack
    sw, $s3, 4($sp)     # save $s3 on the stack
    sw, $s4, 0($sp)     # save $s4 on the stack

    move $s0, $a0       # copy parameter $a0 into $s0
    move $s1, $a1       # copy parameter $a0 into $s1
    move $s2, $a2       # copy parameter $a0 into $s2
    move $s3, $a3       # copy parameter $a0 into $s3
    move $s4, $zero     # s4 is a character counter. $s4 = 0
getsLoop:
    addi $t0, $zero, 0x00   # Put NULL ascii character inside $t0
    sll $t1, $s4, 2     # create buffer storing address ($t1 = $s1 * 4)
    add $t2, $s0, $t1   # register #t2 now holds buffer address
*   lw $t3, ($s0)       # load char into #t3
    beq $t3, $t0, exitPuts  # exit puts if the current character is the NULL character

    move $a0, $t3       # put the character to print inside $a0, accessible by putchar
    jal putchar     # print char using putchar
    addi $s0, $s0, 1    # character count += 1
    j getsLoop      # Loop to print next character
exitPuts:
    lw $s4, 0($sp)      # restore stack
    lw $s3, 4($sp)      # -
    lw $s2, 8($sp)      # -
    lw $s1, 12($sp)     # -
    lw $s0, 16($sp)     # -
    lw $ra, 20($sp)     # -
    addi $sp, $sp, 20   # pop from stack
    jr $ra          # return