我正在尝试将 MIPS 代码转换为 ARM 代码,这不是问题,因为我遇到了一个棘手的异常,我希望有人能解释什么是错误的以及如何处理它。程序传递 a0,它是指向 mips 二进制指令表示的指针,它返回 $v0 创建的 ARM 指令的数量和 $v1 - 指向第一条 arm 指令的指针。test.s(ta 用来测试的代码)然后执行一些操作来测试程序是否成功。如果你愿意,我可以给你看 test.s。无论如何,我不断收到的错误如下......
Exception occurred at PC=0x00400140
Unaligned address in inst/data fetch: 0xfffffffb
Exception 4 [Address error in inst/data fetch] occurred and ignored
Exception occurred at PC=0x00400144
Unaligned address in inst/data fetch: 0xfffffff7
Exception 4 [Address error in inst/data fetch] occurred and ignored
Read from unused memory-mapped IO address (0xfffffff4)
.data
.align 2
mipsArray: .word 0
mipsToArm: .word 0
branchTable: .word 0
armArray: .word 0
# endConditon: .word 0xFFFFFFFF
.text
#----------------------------------------------------------------------#
# Current Register list:
# $t0 - is initially used as a pointer to the mipsArray
# $a0 - holds the pointer to the first word of the mips array
# $s1 - will hold the current word as we check for FFFFFFFF
# $s8 - will hold the check value 0xFFFFFFFF
#----------------------------------------------------------------------#
MIPStoARM:
addi $sp, $sp, -4 # prep the frame
sw $fp, 0($sp) # prep the frame
move $fp, $sp # prep the frame
addi $sp, $sp, -36 # prep the frame
sw $ra, -4($fp) # prep the frame
sw $s8, -8($fp) # prep the frame
sw $s1, -12($fp) # prep the frame
sw $s2, -16($fp)
sw $s3, -20($fp)
sw $s4, -24($fp)
sw $s5, -28($fp)
sw $s6, -32($fp)
sw $s7, -36($fp)
la $t0, mipsArray # store the pointer into data as a global
sw $a0, 0($t0)
li $s8, 0xFFFFFFFF # this is the check value
addi $t1, $0, 1 # for now t1 is the counter = 1
lw $s1, 0($a0)
countLoop:
beq $s1, $s8, allocateSpace # if word == FFFFFFFF then allocate the space
add $a0, $a0, 4 # move to next word
lw $s1, 0($a0)
addi $t1, $t1, 1 # counter++
j countLoop
allocateSpace:
sll $t1, $t1, 2 # count * 4 to get number of words
li $v0, 9
add $a0, $0, $t1
syscall
move $t2, $v0 # t2 now holds the pointer to the beginning of the allocated space
la $t0, mipsToArm
sw $t2, 0($t0) # now mipstoarms first element is the pointer to the allocated space
li $v0, 9
syscall
move $t2, $v0 # t2 now holds the pointer to the beginning of the allocated space
la $t0, branchTable
sw $t2, 0($t0) # now branchTable first element is the pointer to the allocated space
sll $t1, $t1, 1 # now multiply the counter by 2 to make enough space for armArray
li $v0, 9
add $a0, $0, $t1
syscall
move $t2, $v0
la $t0, armArray
sw $t2, 0($t0) # now armArray first element is the pointer to the allocated space
#--------------------------------------------------------------------#
# from this point on should be the translation mips to arm
# first load the first word then
# th e main switch case which checks opcode
#
# notes on current register usage:
# s1 - points to the mips binary data
# s2 - points to the mips to arm
# s3 - points to the branch table
# s4 - points to the arm array
# s5 - this boyo is gonna count how many arm instructions there are
# s8 - 0xFFFF FFFF
# t0 - is temp used to loading double pointers
# t2 - will hold the current word like a boss
#---------------------------------------------------------------------#
wordSetup:
la $t0, mipsArray #loads the address of mipsarray which first word conains the pointer
lw $s1, 0($t0) # load the pointer
la $t0, mipsToArm
lw $s2, 0($t0)
la $t0, branchTable
lw $s3, 0($t0)
la $t0, armArray
lw $s4, 0($t0)
lw $t2, 0($s1) # t2 should now hold the current word
move $s5, $0 # initialize the counter to 0
move $t3, $0 # initialize to 0
beq $t2, $s8, done # this will have to be changed for Part2
addi $s5, $s5, 1 # counter++
j opcodeSwitch # jump to the main switch
nextWord:
addi $s1, $s1, 4 # sets the MIPS to point to next word
lw $t2, 0($s1)
addi $s2, $s2, 4 # points to next word in MIPStoARM
addi $s3, $s3, 4 # points to next word in branctable
beq $t2, $s8, done # if the current word is 0xFFFFFFFF your done part 1
opcodeSwitch:
# first step here is to mask out the 6 most significant bits
li $t6 0xFC000000
and $t3, $t2, $t6 # mask out opcode save into t3
beq $t3, $0, zeroOpHandler # checks if the opcode is 000000
li $t6, 0x04000000
beq $t3, $t6, oneOpHandler # checks if the opcode is 000001
li $t6, 0x10000000
beq $t3, $t6, fourOpHandler # checks if the opcode is 000100
li $t6, 0x20000000
beq $t3, $t6, eightOpHandler # checks if the opcode is 001000
li $t6, 0x30000000
beq $t3, $t6, cOpHandler # checks if the opcode is 001100
li $t6, 0x34000000
beq $t3, $t6, dOpHandler # checks if the opcode is 001101
#---------------------------------------------------------------------#
# ~~~zeroOpHandler:
#---------------------------------------------------------------------#
zeroOpHandler:
li $t6, 0x001FFFFF
and $t3, $t2, $t6
li $t6, 0x00000008
beq $t3, $t6, jRHandler
andi $t3, $t2, 0x7FF
li $t6, 0x024 # this should represent the AND func.
beq $t3, $t6, oaasHandler # if it matches go to oaasHandler
li $t6, 0x025 # this should represent the OR func.
beq $t3, $t6, oaasHandler # if it matches go to orHandler
li $t6, 0x020 # this should represent the ADD func.
beq $t3, $t6, oaasHandler # if it matches go to oaasHandler
li $t6, 0x022 # this should represent the SUB func.
beq $t3, $t6, oaasHandler # if it matches go to oaasHandler
li $t6, 0x006 # this should represent the SRLV func.
beq $t3, $t6, srlvHandler # if it matches go to srlvHandler
li $t6, 0x004 # this should represent the SLLV func.
beq $t3, $t6, sllvHandler # if it matches go to sllvHandler
andi $t3, $t2, 0x3F
li $t6, 0x03 # this should represent the SRA func.
beq $t3, $t6, sraHandler # if it matches go to sraHandler
li $t6, 0x02 # this should represent the SRL func.
beq $t3, $t6, srlHandler # if it matches go to srlHandler
li $t6, 0x00 # this should represent the SLL func.
beq $t3, $t6, sllHandler # if it matches go to sllHandler
#---------------------------------------------------------------------#
oneOpHandler:
fourOpHandler:
eightOpHandler:
cOpHandler:
dOpHandler:
######
srlvHandler:
sllHandler:
sllvHandler:
srlHandler:
sraHandler:
#---------------------------------------------------------------------#
# ~~~AND HANDLER
#---------------------------------------------------------------------#
oaasHandler:
#this handles or, and, sub, add.
li $s6, 0xE0000000
li $t6, 0x03E00000
and $t3, $t6, $t2 # mask out s register
srl $t3, $t3, 5 # move s into the corresponding spot for ARM
li $t6, 0x001D0000 # set t6= 29 in position
bne $t3, $t6, oRnSecCheck
li $s6, 0xE00D0000 # if it is == then set rn in arm to 13
j oaasRmReg
oRnSecCheck:
li $t6, 0x001F0000
bne $t3, $t6, oRnThirdCheck
li $s6, 0xE00E0000
j oaasRmReg
oRnThirdCheck:
li $t6, 0x000D0000
slt $t6, $t3, $t6
bne $t6, $0, oRnNoRegTrans
# set instruction to MOV R0 R0
li $s6, 0xE1B00000
j setTables
oRnNoRegTrans:
or $s6, $s6, $t3
j oaasRmReg
#-----------------------------------------------------------------#
# this next part deals with the rm register
#-----------------------------------------------------------------#
oaasRmReg:
li $t6, 0x001F0000 # prepare the mask
and $t3, $t2, $t6 # mask out Rm
srl $t3, $t3, 16 # move s into position for arm
li $t6, 0x0000001D # set t6= 29 in position
bne $t3, $t6, oRmSecCheck
li $t3, 0x0000000D # if it is == then set rn in arm to 13
or $s6, $s6, $t3 # set corresponding bits to 13
j oaasRdReg
oRmSecCheck:
li $t6, 0x0000001F
bne $t3, $t6, oRmThirdCheck
li $t3, 0x0000000E
or $s6, $s6, $t3 # set corresponding bits to 14
j oaasRdReg
oRmThirdCheck:
slti $t6, $t3, 0x0000000D
bne $t6, $0, oRmNoRegTrans
# set instruction to MOV R0 R0
li $s6, 0xE1B00000
j setTables
oRmNoRegTrans:
or $s6, $s6, $t3
j oaasRdReg
#-----------------------------------------------------------------#
# this next part deals with the rd register
#-----------------------------------------------------------------#
oaasRdReg:
li $t6, 0x0000F800 # prepare the mask
and $t3, $t2, $t6 # mask out Rm
sll $t3, $t3, 1 # move s into position for arm
li $t6, 0x0001D000 # set t6= 29 in position
bne $t3, $t6, oRdSecCheck
li $t3, 0x0000D000 # if it is == then set rn in arm to 13
or $s6, $s6, $t3 # set corresponding bits to 13
j oaasSetOpCode
oRdSecCheck:
li $t6, 0x0001F000
bne $t3, $t6, oRdThirdCheck
li $t3, 0x0000F000
or $s6, $s6, $t3 # set corresponding bits to 14
j oaasSetOpCode
oRdThirdCheck:
li $t6, 0x0000D000
slt $t6, $t3, $t6
bne $t6, $0, oRdNoRegTrans
# set instruction to MOV R0 R0
li $s6, 0xE1B00000
j setTables
oRdNoRegTrans:
or $s6, $s6, $t3
j oaasSetOpCode
oaasSetOpCode:
# this is a switch statement similar to the main switch to set opcode
# for oaas cases
andi $t3, $t2, 0x7FF
li $t6, 0x024 # AND
bne $t6, $t3, oOROpCode
j setTables # go straight to setTables because opcode = 0000
oOROpCode:
li $t6, 0x00000025
bne $t6, $t3, oADDOpCode # OR opcode
li $t3, 0x01800000
or $s6, $s6, $t3 # place theopcode in the arm instruction
j setTables
oADDOpCode:
li $t6, 0x00000020 # AND opcode
bne $t6, $t3, oSUBOpCode
li $t3, 0x00800000
or $s6, $s6, $t3 # place theopcode in the arm instruction
j setTables
oSUBOpCode:
#li $t6, 0x00000022
# here we will probably want to add a bne and maybe branch to srlv or sllv
# once we understand how to handle them
li $t3, 0x00400000
or $s6, $s6, $t3
j setTables
#---------------------------------------------------------------------#
# ~~~JR HANDLERctions that we will be needing are listed below.
#---------------------------------------------------------------------#
jRHandler:
move $s7, $0 # set the branch flag to 0 (off)
li $t6, 0x03E00000
and $t3, $t6, $t2 # mask out the s register
srl $t3, $t3, 21 # move it to least significant bits
li $t6, 0x0000001D # here we check if the register is 13
bne $t3, $t6, secondCheck # if it isnt move to next check
li $s6, 0xE12FFF1D # if it is this is the ARM translation store in s6
# now we have to put the word into the arm table and save the address in the
# mips to arm table and set the equivalent offset in the branchtable to 0
j setTables
secondCheck:
li $t6, 0x0000001F
bne $t3, $t6, thirdCheck # if the register isnt 31 jump to noRegTrans
li $s6, 0xE12FFF1E # else this is the ARM translation
# now we have to put the word into the arm table and save the address in the
# mips to arm table and set the equivalent offset in the branchtable to 0
j setTables
thirdCheck:
slti $t6, $t3, 0xD # check if s < 13 t6 = 1 else t6 = 0
bne $t6, $0, noRegTrans
li $s6, 0xE1B00000
j setTables
noRegTrans:
li $s6, 0xE12FFF10
or $s6, $s6, $t3 # or the register number into the format
j setTables # then jump to set Tables
#-------------------------------------------------------------------#
setTables:
bne $s7, $0, branchSetTables
addi $s4, $s4, 4
addi $s5, $s5, 1 # ARMcounter++
sw $s6, 0($s4) # place the ARM instruction in the ARM array
sw $s4, 0($s2) # store the ARM tables address in miptoarm
sw $0, 0($s3) # stores a 0 in the branch table
j nextWord
branchSetTables:
done:
move $v0, $s5
la $t0, armArray
lw $v1, 0($t0)
lw $ra, -4($fp) # prep the frame
lw $s8, -8($fp) # prep the frame
lw $s1, -12($fp) # prep the frame
lw $s2, -16($fp)
lw $s3, -20($fp)
lw $s4, -24($fp)
lw $s5, -28($fp)
lw $s6, -32($fp)
lw $s7, -36($fp)
addu $sp, $sp, 40 # pop
lw $fp, -4($sp)
jr $ra