我有一个任务,建立一个计算器在mips,我需要从用户那里得到符号,并使用这个操作数进行计算。我把操作数保存在数据中,我想让他们比较。我不知道我做错了什么,但这是行不通的。
.data
IfStart: .asciiz "Start Calculator? (0: no, 1: yes):"
msg: .asciiz "Enter operation symbol (+, -, *) or ‘!’ to quit:"
mulb: .asciiz "*"
addb: .asciiz "+"
subb: .asciiz "-"
stopsign: .asciiz "!"
newline: .asciiz "\n"
pick1: .asciiz "Enter first number (A):"
pick2: .asciiz "Enter second number (B):"
badnumber: .asciiz "Bad input\n"
bye: .asciiz "Good bye!"
one: .word 1
result: .asciiz "The result is:"
buffer: .space 20
.text
main:
li $v0,4
la $a0,IfStart
syscall
li $v0,5 #get number from user
syscall
move $t0,$v0
lw $t1, one
beq $t1,$t0,if1
beq $zero,$t0,if0
li $v0,4
la $a0,badnumber
syscall
li $v0,4
la $a0,bye
syscall
li $v0,10
syscall
if1:
jal Calculator
if0:
li $v0,4
la $a0,bye
syscall
li $v0,10
syscall
Calculator:
li $v0,4 #print first message
la $a0,msg
syscall
li $v0,8 #take in input
la $a0, buffer #load byte space into address
li $a1, 20 # allot the byte space for string
move $t2,$a0 #save string t2
syscall
li $v0,5 #Read int A
syscall
move $t0,$v0 #t0 is A
li $v0,5 #Read int B
syscall
move $t1,$v0 #t1 is B
lw $t3, mulb #mul sign
lw $t6, subb #sub sign
lw $t4, stopsign
lw $t5, addb #add sign
beq $t3,$a0,stop
beq $t4,$a0,multp
beq $t5,$a0,adds
beq $t6,$a0,subbs
multp:
jal Multiply
j print
adds:
jal Sum
j print
subbs:
jal Substract
print:
li $v0,4 #print the result is:
la $a0,result
syscall
#print result
li $v0, 1
move $a0, $t3
syscall
li $v0,4 #print new line
la $a0,newline
syscall
jal Calculator
stop:
li $v0,10
syscall
在执行下列其中一个数据列之后:
lw $t4, stopsign
lw $t5, addb #add sign
李世民总是不停地写信给我这个错误:Runtime exception at 0x004000b8: fetch address not aligned on word boundary 0x1001005a
但类似的行:
lw $t3, mulb #mul sign
lw $t6, subb #sub sign
完全没有问题。是字符做的问题(!/+)吗?
谢谢你的帮助!
1条答案
按热度按时间irtuqstp1#
MIPS和其他RISC CPU有一个限制,这个限制就是对齐规则。(ARM和Motorola 68000在较小程度上是相似的。)如果使用
lw
加载32位值,则该值的地址需要是4的倍数。更简单地说,它需要以0、4、8或C结尾。另一方面,阅读字节时,可以在任何地址处进行,而不管对准如何。使用正确的load命令之所以如此重要,* 是因为CPU不知道数据的类型。* 当您使用
.word
、.byte
或.asciiz
指令输入数据时,您使用的是对您(程序员)最方便的格式。然而,当您的源代码转换为可执行程序时,数据的类型信息将丢失。假设您有以下内容,并且假设下面的标签“MyString”与4的倍数对齐(即,其地址以0、4、8或C结尾)。这里实际发生的是
0x31323300
值被加载到$t1
中(假设是big-endian体系结构,但这是一个完全不同的蠕虫)。这意味着字符串“123”和整数0x31323300
(十进制,825,373,400),* 在CPU内存中具有相同的表示形式,并且完全可以互换。* 通过在字符串上使用lw
,您得到的实体与预期的完全不同,即使数据本身根本没有改变!