linux-使用-O1和内联汇编程序的GCC分段错误
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了linux-使用-O1和内联汇编程序的GCC分段错误,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含1366字,纯文字阅读大概需要2分钟。
内容图文
![linux-使用-O1和内联汇编程序的GCC分段错误](/upload/InfoBanner/zyjiaocheng/948/b3c96ddca02441bebd1c8af18ad34bed.jpg)
我在我的代码中检测到一个奇怪的分段错误,如果这可能是GCC错误,还是我的错,我想听听您的意见!
该函数如下所示:
void testMMX( ... ) {
unsigned long a = ...;
unsigned char const* b = ...;
unsigned long c = ...;
__asm__ volatile (
"pusha;"
);
__asm__ volatile ( "mov %0, %%eax;" : : "m"( a ) : "%eax" ); // with "r"( a ) it just works fine!
__asm__ volatile ( "add %0, %%eax;" : : "m"( b ) : "%eax" );
__asm__ volatile ( "mov %0, %%esi;" : : "m"( c ) : "%eax", "%esi" );
__asm__ volatile (
"sub %eax, %esi;"
"dec %esi;"
"movd (%esi), %mm0;"
"popa;"
);
}
如果我使用-O0进行编译,则效果很好.但是它使用-O1和-O2进行SegFaults.我花了很长时间才弄清楚此段错误是由帧指针遗漏引起的. pusha指令将堆栈大小增加4 * 8 = 32字节(x86_32),因此ESP也应增加.但是gcc无法识别这一点.如果我手动添加ESP修复程序
__asm__("add $32, %esp")
或在gcc中使用“ -fno-omit-frame-pointer”标志,我可以使用-O1和-O2进行编译和运行,而不会出现任何错误!
所以我现在的问题是:如果启用了帧指针省略功能,为什么gcc不能通过任何push / pop内联汇编程序来调整ESP?这是gcc错误吗? gcc甚至能够检测到这一点吗?我想念什么吗?
解决这个问题将非常有趣.
提前致谢!
解决方法:
否-gcc无法检测到这一点.它不对asm块中出现的指令进行任何分析.您有责任将任何副作用通知编译器.您能解释一下您正在执行的测试吗?
另外,您应该考虑为该代码使用单个asm块; volatile可能会阻止对asm块进行重新排序,但是您会选择cannot assume this yields consecutive instructions.
内容总结
以上是互联网集市为您收集整理的linux-使用-O1和内联汇编程序的GCC分段错误全部内容,希望文章能够帮你解决linux-使用-O1和内联汇编程序的GCC分段错误所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。