0

Below you see a code snippet:

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;\

I get a segmentation fault in line.

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

if I change the array size from 256KB to say 7MB or 6MB; I do not get any error. It can't be the problem that I don't have the space right?

I tried to examine the dump. It does not give me much clue.

Here it is

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

and here is the back trace.

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

Any idea what the problem could be?

Thanks.

5
  • "It can't be the problem that I don't have the space right?" - it is exactly the problem. The stack is not quite big, and it can easily owevrflow. How about making your array static (with all its side effects taken in consideration)? Commented Jun 11, 2013 at 13:44
  • 2
    The source is truncated, but aside from that, you cannot be assured that values you store in registers will be preserved between __asm__ blocks. gcc does not perform any analysis of the instructions - it only knowns inputs, outputs, and clobbers. e.g., %eax or %ecx might be used as loop variables. Commented Jun 11, 2013 at 13:49
  • @H2CO3: that's one solution. I need to look into static arrays first! Commented Jun 11, 2013 at 13:49
  • @BrettHale: Do you suggest another method to fill the cache lines then? Commented Jun 11, 2013 at 13:53
  • I suggest you step through a few iterations of the loop and see if the registers reflect the values you expect. Also, look at the assembly generated by the compiler for this function. %ebx is also used for PIC in the i386-ELF ABI - but that's a problem for later. Commented Jun 11, 2013 at 14:19

1 Answer 1

2

Inline assembly is dangerous. You should pay attention to these things:

  1. Let gcc know what you're messing with. For example, you're changing ecx, and gcc may assume that ecx holds some value. You the "clobber" section of the inline assembly (e.g. __asm__("movl $0x0, %ecx":::"ecx").

  2. Don't assume that registers don't change between inline assembly lines. Even with no C line in between, gcc may insert assembly code there. Use a single inline assembly block, with multiple assembly commands.

  3. If you need to pass data between assembly blocks, do it using a C variable. You can define it as register to make it fast. You can even choose which register you want in gcc (I forgot the exact syntax).

Sign up to request clarification or add additional context in comments.

5 Comments

@user2015933, an example for your code - you put a value in ecx, then enter the loop, then look at ecx. Perhaps the loop control code modifies ecx?
ecx does have a value there - 0x00. and 16 is added for every iteration.
I don't know which registers gcc uses for loop control. Surely some registers are used, maybe not ecx, but it depends on compiler version and flags.
Thanks for those useful tips. Any insight into the problem will be appreciated.
As far as I can tell, not following these guidelines is the reason for the problem.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.