首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >G77编译程序中令人困惑的堆栈行为

G77编译程序中令人困惑的堆栈行为
EN

Stack Overflow用户
提问于 2014-09-07 06:41:52
回答 1查看 81关注 0票数 0

我得到了C++和Fortran77的混合体,它们都是用G77编译的。它主要是C++,但它调用ODE-solver DVERK,后者随后回调全局C函数以获得导数(用__stdcall声明)。它一直运行良好,直到我得到一个奇怪的SIGSEGV。

我追踪到了这一点,这是因为esp正在降低到它的段边界以下。这样做的原因是DVERK包含**运算符,该运算符在内部是一个函数调用,通过堆栈上的值传递两个双精度值,长度为16个字节。该函数返回答案,但随后我看到了以下指令:

代码语言:javascript
复制
sub 0x10,%esp

这会使堆栈指针递减16个字节,就像是将参数放回堆栈(?)G77似乎在每次函数调用后都会这样做,通常它不会有什么坏处,因为堆栈指针是不变的。然而,在**的情况下,堆栈指针仍然是递减的,如果该代码被执行足够多次,递减就会累积,直到我得到SIGSEGV。(如果有足够的堆栈空间,则不会出现此问题,因为DVERK的返回会将其清除。)

我尝试用dexp(dlog(a)*b)替换代码a**b,但是同样的事情发生了,只是它分两步发生,在dlog之后8个字节,在dexp之后8个字节。

一定是我在设置G77对其运行时库使用的调用约定时做错了什么。感谢您的专业知识。

EN

回答 1

Stack Overflow用户

发布于 2014-09-07 08:27:11

在这个时代,将C或C++与Fortran混合的方法是使用ISO-C_Binding。在C++中,使用extern C调用。在Fortran中使用(英语单词)正在调用的过程的Fortran ISO C绑定。这将导致Fortran使用C的调用约定(ABI)。这样你就不需要了解编译器的内部原理了。为此,您必须使用比g77更现代的Fortran编译器,例如gfortran。gfortran完全能够编译FORTRAN 77。正式地说,ISO-C绑定是Fortran2003的一部分--您可以在C++和现有的FORTRAN77之间编写一个包装器。

有一个Stackoverflow标签解释了ISO-C绑定:https://stackoverflow.com/tags/fortran-iso-c-binding/info

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/25705443

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档