13

I am studying how c++ invoke the right member functions through assembly language. The simple program that I come with is as the following:

class A                        
{                              
    public:                    
        virtual void show() {} 
};                             

class B : public A             
{                              
    public:                    
        void show() {}         
};                             


int main()                     
{                              
    A* pA = new B;             
    pA->show();                

    return 0;                  
}                              

its assembly is as the following:

main:
.LFB2:
    .cfi_startproc
    .cfi_personality 0x3,__gxx_personality_v0
    pushq   %rbp
    .cfi_def_cfa_offset 16
    movq    %rsp, %rbp
    .cfi_offset 6, -16
    .cfi_def_cfa_register 6
    pushq   %rbx
    subq    $24, %rsp
    movl    $8, %edi
    .cfi_offset 3, -24
    call    _Znwm            <<<================ 1
    movq    %rax, %rbx
    movq    %rbx, %rax
    movq    %rax, %rdi
    call    _ZN1BC1Ev
.L11:
    movq    %rbx, %rax
    movq    %rax, -24(%rbp)
    movq    -24(%rbp), %rax
    movq    (%rax), %rax
    movq    (%rax), %rdx
    movq    -24(%rbp), %rax
    movq    %rax, %rdi
    call    *%rdx             <<<=== 2
    movl    $0, %eax
    addq    $24, %rsp
    popq    %rbx
    leave
    ret
    .cfi_endproc

my questions are:

  1. I searched google for nwm, it only tells me that c++ uses it to allocate memory, could some one tell me more about it ? is it in one lib? if possible, can i get its source code? how?
  2. i am not quite familiar with this syntax, what does it want to do ?
Jonathan Potter
  • 36,172
  • 4
  • 64
  • 79
Alex
  • 1,737
  • 2
  • 20
  • 35
  • 2
    your code leaks memory,btw ... every new must be matched with a delete ... – Goz Sep 30 '13 at 06:52
  • 4
    @Goz: Chances are that Alex already knows this and simply wanted to create a [Short, Self Contained, Correct (Compilable), Example](http://meta.stackexchange.com/questions/22754/sscce-how-to-provide-examples-for-programming-questions). – Martin Liversage Sep 30 '13 at 06:58
  • @Goz, I think that Martin Liversage has already answered your concern, thanks Martin for your answer and thanks Goz for pointing it out for me. – Alex Sep 30 '13 at 07:16
  • 1
    You will typically see this `call *%reg` in compiled C++ code where a virtual method is called using dynamic dispatch. `_Znwm` is the name mangling of the `::operator new (size_t)` function. – Brett Hale Sep 30 '13 at 15:18
  • possible duplicate of [What does an asterisk \* before an address mean in x86-64 AT&T assembly?](http://stackoverflow.com/questions/9223756/what-does-an-asterisk-before-an-address-mean-in-x86-64-att-assembly) +1 because I also came here after decompiling `virtual` :-) – Ciro Santilli OurBigBook.com Jun 18 '15 at 15:38

1 Answers1

19

The * is used before absolute addresses in AT&T assembly syntax for call or jump instructions. This means it will jump to the address contained in the register. The alternative is a relative jump, which is relative to the current instruction.

From the GNU as manual:

AT&T absolute (as opposed to PC relative) jump/call operands are prefixed by `*'; they are undelimited in Intel syntax.

In your code it makes sense for there to be a call to an address in a register. Calling pA->show() requires a look up to see what the right function to be called is. This is because it is a virtual function on class A.

Gavin Smith
  • 3,076
  • 1
  • 19
  • 25
  • I am writing this to make sure that I understand it correctly. according to the link that you provided, does it mean that it will call the function which starts at the address stored in that register? – Alex Sep 30 '13 at 07:21
  • @GavinSmith, Can a register also contain an offset you could jump to, instead of an absolute adress? Otherwise this citation wouldn't make sense anyway. – Devolus Sep 30 '13 at 08:55