数组大小 - 分段错误 - C.

时间:2013-06-11 13:38:21

标签: c assembly segmentation-fault

下面你会看到一个代码段:

int foo[262144]  __attribute__ ((aligned (8192)));

void
test49()
{
    __asm__("movl $0x0, %ecx");
    __asm__("movl %0,%%eax"::"r"(&foo));

#ifdef FOREVER
    while(1)
    {
#else
    for(int i=0; i < iters; i++)
    {
#endif
        __asm__("test_begin: addl $0x1,%ecx;");
        __asm__("mov 0x00(%eax),%ebx;\

我遇到了分段错误。

    __asm__("mov 0x00(%eax),%ebx;\

如果我将数组大小从256KB更改为7MB6MB;我没有得到任何错误。这不是我没有空间的问题吗?

我试图检查转储。它没有给我太多线索。

这是

./microbenchmark 49
Performing Test49
[1]    12011 segmentation fault (core dumped)  ./microbenchmark 49

这是后面的痕迹。

gdb microbenchmark core
GNU gdb (GDB) SUSE (7.5.1-2.1.1)
Copyright (C) 2012 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-suse-linux".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from /MB/test-l2-256/test-hit/microbenchmark...done.
[New LWP 12011]
Missing separate debuginfo for /lib/libc.so.6
Try: zypper install -C "debuginfo(build-id)=7e0834d74d3e93c3210d2405cde86dc995fe476c"
Missing separate debuginfo for /lib/ld-linux.so.2
Try: zypper install -C "debuginfo(build-id)=6a687db0baedc0db516006a7eedaee8f57f955c8"
Core was generated by `./microbenchmark 49'.
Program terminated with signal 11, Segmentation fault.
#0  0x08048603 in test49 () at microbenchmark.c:77
77              __asm__("mov (%eax),%ebx;\
(gdb) bt
#0  0x08048603 in test49 () at microbenchmark.c:77
#1  0x08048538 in main (argc=2, argv=0xfff68fb4) at microbenchmark.c:33

知道问题可能是什么?

感谢。

1 个答案:

答案 0 :(得分:2)

内联汇编很危险。你应该注意这些事情:

  1. 让gcc知道你在搞什么。例如,你正在改变ecx,gcc可能会认为ecx拥有一些价值。您是内联汇编的“clobber”部分(例如__asm__("movl $0x0, %ecx":::"ecx")

  2. 不要假设内联装配线之间的寄存器不会发生变化。即使中间没有C线,gcc也可以在那里插入汇编代码。使用单个内联汇编块,具有多个汇编命令。

  3. 如果需要在程序集块之间传递数据,请使用C变量执行此操作。您可以将其定义为register以使其快速。你甚至可以在gcc中选择你想要的寄存器(我忘了确切的语法)。