【问题标题】:how to run MIPS program without main and call MIPS program from C program如何在没有 main 的情况下运行 MIPS 程序并从 C 程序调用 MIPS 程序
【发布时间】:2016-02-24 11:50:01
【问题描述】:

很长的问题,提前抱歉。好的,所以我正在处理一些不寻常的限制,这就是为什么到目前为止我还没有在网上找到太多帮助的原因。主要限制是我不能使用模拟器,因此我不能使用系统调用。我需要用 MIPS 和 C 做一些事情,但对这些程序的执行方式知之甚少,无法理解如何让它们按照我需要的方式工作。 首先,按照我教授的指示,我需要创建一个名为“rng.s”的文件。他还指定它应该以以下代码开头:

.abicalls
.option pic0
.globl rng, seed
.set nomips16

据我了解,这意味着我正在创建两个函数“rng”和“seed”,而我不需要创建主函数。在为早期作业提供的模板中,有一些代码如下所示:

.ent main
.type main, @function

我不确定我是否需要在这里用我的函数 rng 和 seed 做类似的事情。此外,当我不包括 main 时,汇编器会返回一个错误。稍后在作业中,我应该编写一个调用函数 rng() 的 C 程序(与我的 MIPS 程序中编写的相同)并传递一些值。我不太明白如何从我的 C 程序内部调用 rng() 。一开始我是这样尝试的:

#include<stdio.h>

int main(int argc, char* argv[])
{
    //int a, b, c are input from command line using atoi(argv)
    //i've tested it and that part works fine, so it's not important
    rng(a, b, c);
    return 0;
}

我的教授包含了一个 Makefile,它应该将两个程序编译成一个可执行文件,但如果我尝试使用它,我会收到错误,因为 main 有多个声明。

所以最大的问题是如何让我的 MIPS 程序在没有 main 的情况下运行? 然后如何从我的 C 程序内部调用我的 MIPS 程序内部的函数?

我已经在这上面花了两天时间,但我一无所获,所以任何帮助都将不胜感激。谢谢你。

【问题讨论】:

  • 查找 MIPS ABI 的文档(教授可能已经给出了一些参考资料),或者只是查看 gcc 为调用您的函数的 main() 生成的汇编代码(参见选项 -c-S)。
  • 我在理解上遇到了一些麻烦,您在哪种架构上混合了 C 和 MIPS。 MIPS 通常在典型 PC 上的模拟器中运行是有原因的。
  • 据我了解,当两个程序都转换为目标文件时,它如何到达那里并不重要,这些文件现在能够在进行编译的机器的体系结构上运行/assemble,因此能够一起工作。所以我相信 Makefile 通过汇编程序运行我的 MIPS 程序,通过 gcc 运行我的 C 程序。我想这主要是在弄清楚如何使这些程序进行通信的练习。我只需要了解如何促进这种沟通的细微差别。
  • 我可以想象将 C 编译成 MIPS 架构,但是将 MIPS 编译成原生 x86 听起来有点不可思议。撇开这个问题不谈,你应该关心创建目标文件而不是处理结果是对的。从 MIPS 中创建一个不包含 main 方法的目标文件应该是完全可能的。如果您不确定如何操作,您可能想通过将rng 编程到一个单独的 .c 文件并将其编译为目标汇编代码来“作弊”。
  • 如果我只关注结果,我可以这样做,但由于这是一项作业,我的教授将查看我的所有源代码。所以我必须按照我被指示的方式去做。不过不用担心,我想我已经弄清楚了。事实证明,正如你所说,我不需要声明 main,我可以像声明 main 一样声明 rng。如果我这样做并尝试单独编译 MIPS 程序,那么编译器会抛出错误,但如果我使用将两个程序一起编译的 Makefile,那么它会理解 main 已在 C 程序中声明并编译得很好。

标签: c mips mips32


【解决方案1】:

好的,所以我花了一段时间,但我终于得出了答案。我知道其中很多可能很简单,但我只是为了任何像我一样困惑的可怜的灵魂而把它放在那里。所以这是我对这两个问题的发现:

1:如何在没有 main 的情况下运行我的 MIPS 程序

当程序被汇编时,某处需要有一个 main。单独组装时,程序需要在头文件中声明 main。像这样:

.abicalls
.option pic0
.globl main
.set nomips16
.ent main
.type main, @function

这告诉您的程序 main 是一个函数,并且您正在 main 中输入它。

但是,如果您使用 Makefile 之类的东西来将不同的程序合并到一个成品中,那么可以不在您的 MIPS 程序中声明 main,而是在另一个程序中声明 main,该程序将在同时。在这种情况下,您只需对 main 执行相同的操作,但使用您将开始的函数(执行程序时要首先运行的函数),如下所示:

.abicalls
.option pic0
.globl rng, seed
.set nomips16
.ent rng
.type rng, @function

注意我是如何使用 .globl rng,seed 的。据我了解,这允许您从编译到成品中的其他程序调用这两个函数(rng 和种子)。

2:如何从我的 C 程序调用用我的 MIPS 程序编写的函数

问题中发布的 C 示例可以解决问题。事实证明,MIPS 程序将获取这些参数(a、b、c)并将它们放入寄存器 $a0-$a2。然后你只需要格式化你的程序,将返回值放入 $v0 中,然后可以将其反馈到 C 程序中。举个例子:

// C Program
//=========================
#include<stdio.h>
int main()
{
    printf("%d", rng(0));
    return 0;
}
//=========================

// MIPS program
//=========================
rng:
    addi $v0, $a0, 1
    jr   $ra
//=========================

运行 C 程序将简单地输出 1,因为它调用 rng() 将 1 添加到输入(在 C 程序设置为 0 的 $a0 中找到)并在退出前将其放入 $v0。然后 printf 打印出 rng 返回的内容,即 1。

所以你有它。感谢您对互联网的帮助。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-04-18
    • 1970-01-01
    • 2016-04-17
    • 1970-01-01
    • 1970-01-01
    • 2010-10-18
    • 2021-04-07
    • 1970-01-01
    相关资源
    最近更新 更多