我正在编写简单的SMIPS汇编测试,以便在HDL定义的处理器上运行。
例如,我有以下代码应该生成溢出异常:
main:
#Test Overflow Exception
addi $2, $0, 0xffffffff
addi $3, $2, 0x1
我知道如果处理器正在做正确的事情,它应该重定向到位于地址0xdeadbeef
的处理程序。我知道只为跳转添加标签,就像在上面添加以下代码一样:
overflowHandler:
addiu $5 $0, 1
bne $0, $5, pass
有没有办法让overflowHandler代码从正确的0xdeadbeef地址开始? 主要从地址0开始吗?
编辑:(我可以控制HDL中描述的处理器的跳转地址)
由于我可以从Bluespec中的处理器设计描述中控制处理器跳转地址,因此我可以将其更改为可被4整除并跳转到更接近更方便的位置。所以我的问题是:地址是否从主要开头的地址0x0开始计数? 什么是最好的解决方案? :更改地址跳转,或标签对应吗?
提前致谢,
答案 0 :(得分:0)
由于您的处理器是在Bluespec中建模的,因此似乎要使用Verilog的$readmemh()函数将要执行的代码加载到处理器的内存中,该函数读取包含内存内容的文本文件。 Bluespec模型创建者可以使用$readmemh()
函数的参数和文本文件中的地址说明符来决定将加载代码的地址。
使用内存内容创建文本文件的最简单方法是通过MIPS汇编程序运行汇编源代码,并从汇编程序的源代码清单中提取十六进制操作码。
问题:“地址是否从地址0x0开始计数?”
MIPS处理器在重置时开始在0x1cf00000
执行代码。 (Simple MIPS处理器在重置时从0x00001000
开始。)您通常会在重置地址跳转到测试程序的开头。如果您加载要在地址0x0
执行的测试程序,则JR $zero
应该有效。
测试程序中的分支都应该是相对地址,因此您无需做任何特殊操作来指定测试代码中的标签地址。如果您需要分支到PASS和FAIL的已知位置,请执行以下操作(假设PASS位于地址0x4000
):
LI $t0, 0x4000
JR $t0
答案 1 :(得分:0)
这个问题没有得到很清楚的回答。通常,某些标签的地址由汇编器(和/或链接器)自动分配,并取决于许多因素。
汇编程序总是有一些指令允许程序员在一定程度上控制代码和标签放在地址空间中的位置。 “org”指令通常用于设置组装过程的当前地址。
在大多数汇编程序中,以下代码将overflowHandler标签设置为0xdeadbeef。
org 0xdeadbeef ; or any other number
overflowHandler:
; some code here
但同样,它取决于特定的汇编语法(并且它们通常在不同的实现中是不同的)。 另一个问题是,即使编译正确,代码也必须在适当的地址上加载到内存中。此任务不是汇编程序任务,而是链接器的任务,操作系统,也取决于使用的二进制文件格式。
请注意,在大多数操作系统中,程序员无法自由选择将加载某些二进制文件的地址。
这里正确的方法是仔细学习用于项目的工具 - 汇编语法(我的意思是汇编指令,而不是处理器指令),链接器功能,使用的二进制格式以及将加载此代码的操作系统函数执行。