MIPS - 获取字边界上未对齐的地址

时间:2017-02-07 23:20:55

标签: mips

我对汇编编程和编程很新,我正在尽力学习。我一直无法将输入存储到变量中,你能帮帮我吗?

当我加载n1和n2的地址或类似的东西时,似乎会出现问题。我试过看类似的问题,不能很好地翻译它们。如果有人有任何在线参考学习,那将非常感激。

这是我的代码:

.data
prompt_n1: .asciiz "Enter first integer n1: "
prompt_n2: .asciiz "Enter second integer n2: "

debug_print: .asciiz "Your numbers are: "

n1: .word 0
n2: .word 0

.text

main:
#Prompt the user for n1.
li $v0, 4
la $a0, prompt_n1
syscall

#Store console: n1
li $v0, 5
syscall

#Attempts to load value of v0 into n1 - Problem Here
la $t0, n1
lw $t1, 0($v0)
sw $t0, 0($t1)

#Prompt the user for n2.
li $v0, 4
la $a0, prompt_n2
syscall

#Store console: n2
li $v0, 5
syscall

#Attempts to load value of v0 into n1 - Problem Here
la $t0, n2
lw $t4, 0($v0)
sw $t0, 0($t4)

j print_statement

print_statement:
li $v0, 4
la $a0, debug_print
syscall

li $v0, 1
lw $a0, n1
syscall

li $v0, 1
lw $a0, n2
syscall

感谢您的时间和帮助。

1 个答案:

答案 0 :(得分:0)

有几个问题......

执行syscall 5获取用户的值后,它位于$v0。您试图使用$t1指令将其传输到lw。但是,您使用$v0作为lw的基地址。如果用户输入的值不是是4的倍数,这将导致对齐异常[正如您所说]

你想要的是move [注册注册]和从内存加载。但实际上,你真的不需要这样做。

相反,只需将$v0存储到n1$t0指向sw。因此,您的n1也不正确。

另外,由于n2.data lw/sw指令后的第一项,因此可能未对齐到四字节边界,因为他们必须对它们使用.align。所以,你需要一个n2指令。

syscall的输入重复了这些问题。

并且,在打印之后,没有什么可以阻止程序,因此它将继续运行,尝试使用在该内存中的任何随机值来获取和执行指令。该程序需要 .data prompt_n1: .asciiz "Enter first integer n1: " prompt_n2: .asciiz "Enter second integer n2: " debug_print: .asciiz "Your numbers are: " space: .asciiz " " # NOTE/BUG: because of the variable length byte arrays above (i.e. the .asciiz # directives), these may not be aligned to a four byte boundary. there are two # solutions: # (1) place n1 and n2 immediately after the .data directive # (2) add a .align directive [as below] .align 4 n1: .word 0 n2: .word 0 .text main: # Prompt the user for n1. li $v0,4 la $a0,prompt_n1 syscall # Store console: n1 li $v0,5 syscall # Attempts to load value of v0 into n1 - Problem Here la $t0,n1 # NOTE/BUG: this is incorrect for several reasons: # (1) $v0 has a value input by the user -- it could be 0, 1, etc. # (2) these are not valid data addresses # (3) if the user enters a value that is _not_ a multiple of four, it # generates an alignment exception # (4) this instruction is just not needed and is just wrong ###lw $t1,0($v0) # NOTE/BUG: $t1 has _not_ been set -- this should use the [correctly] set # register $t0 [which has the address of n1] and should store the value # read from the user ###sw $t0,0($t1) sw $v0,0($t0) # Prompt the user for n2. li $v0,4 la $a0,prompt_n2 syscall # Store console: n2 li $v0,5 syscall # Attempts to load value of v0 into n1 - Problem Here # NOTE/BUG: the lw is commented out for the same reason as above and has # a similar mistake as above la $t0,n2 ###lw $t4,0($v0) ###sw $t0,0($t4) sw $v0,0($t0) j print_statement print_statement: li $v0,4 la $a0,debug_print syscall li $v0,1 lw $a0,n1 syscall # NOTE/BUG: added this to separate the numbers li $v0,4 la $a0,space syscall li $v0,1 lw $a0,n2 syscall # NOTE/BUG: there was no more code here so it just "falls off the end of # the world" -- we need to terminate program execution correctly with the # exit syscall li $v0,10 syscall 才能在执行完毕后正确终止执行。

我已经注释了你的代码,显示了之前和之后的错误修复[请原谅无偿的样式清理]:

{{1}}

一些资源:

http://www.mrc.uidaho.edu/mrc/people/jff/digital/MIPSir.html

http://courses.missouristate.edu/kenvollmar/mars/help/syscallhelp.html

http://logos.cs.uic.edu/366/notes/mips%20quick%20tutorial.htm

http://chortle.ccsu.edu/assemblytutorial/index.html