0

我在大学里研究 Pintos 玩具操作系统,但是在使用 GCC 4.6.2 时有一个奇怪的错误。当我推送我的系统调用参数(内联汇编中只有 3 个 pushl-s)时,堆栈上也会出现一些神秘数据,并且参数的顺序错误。设置 -fno-omit-frame-pointer 可以消除奇怪的数据,但参数的顺序仍然错误。GCC 4.5 工作正常。知道什么具体的选项可以解决这个问题吗?

注意:使用 -O0 时问题仍然存在。

4

3 回答 3

1

如果没有代码示例和不同编译结果的列表,很难为您提供帮助。但以下是您的问题的三个可能原因:

  1. 确保您了解参数是如何被推入堆栈的。论据是从后面推的。这使得printf(char *, ...)检查第一个项目以找出还有多少成为可能。如果你想调用这个函数int foo(int a, int b, int c),你需要按下c,然后是b,最后是 a
  2. 堆栈上的奇怪数据会是返回地址还是 EFLAGS?我不知道 Pintos 以及如何进行系统调用,但请确保您了解 CALL/RET 和 INT/IRET 之间的区别。INT 将标志压入堆栈。
  3. 如果你的内联汇编有副作用,你可能想在它前面写volatile/ 。__volatile__否则 GCC 在优化时允许移动它。

我需要查看您的代码以更好地了解发生了什么。

于 2012-02-26T06:13:05.107 回答
0

罪魁祸首是 -fomit-frame-pointer,它自 4.6.2 起默认启用。-fno-omit-frame-pointer 解决了这个问题。

于 2012-02-28T16:25:09.173 回答
0

你在系统调用之后清理了堆栈上的参数吗?gcc 可能不知道您触摸堆栈并生成代码取决于它预期的堆栈指针。-fno-omit-frame-pointer 强制 gcc 使用 e/rbp 来访问定位数据,但它只是隐藏了实际问题。

于 2012-05-13T18:39:33.427 回答