views:

111

answers:

1

I have some C++ code

#include <cstdio>
#include <boost/bind.hpp>
#include <boost/function.hpp>

class A {
public:
    void do_it() { std::printf("aaa"); }
};

void
call_it(const boost::function<void()> &f)
{
    f();
}

void
func()
{
    A *a = new A;
    call_it(boost::bind(&A::do_it, a));
}

which gcc 4 compiles into the following assembly (from objdump):

00000030 <func()>:
  30:   55                      push   %ebp
  31:   89 e5                   mov    %esp,%ebp
  33:   56                      push   %esi
  34:   31 f6                   xor    %esi,%esi
  36:   53                      push   %ebx
  37:   bb 00 00 00 00          mov    $0x0,%ebx
  3c:   83 ec 40                sub    $0x40,%esp
  3f:   c7 04 24 01 00 00 00    movl   $0x1,(%esp)
  46:   e8 fc ff ff ff          call   47 <func()+0x17>
  4b:   8d 55 ec                lea    0xffffffec(%ebp),%edx
  4e:   89 14 24                mov    %edx,(%esp)
  51:   89 5c 24 04             mov    %ebx,0x4(%esp)
  55:   89 74 24 08             mov    %esi,0x8(%esp)
  59:   89 44 24 0c             mov    %eax,0xc(%esp)
  ; the rest of the function is omitted

I can't understand the operand of call instruction here, why does it call into itself, but with one byte off?

+10  A: 

The call is probably to an external function, and the address you see (FFFFFFFC) is just a placeholder for the real address, which the linker and/or loader will take care of later.

I. J. Kennedy
Yeah this is the correct answer. You'll see tons of these if you objdump an unlinked .o file.
Dan Olson
Yes, that was it. I, indeed, was objdumping an *.o file.
Alex B