Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

x86-64 assembler for polymorphic call

I have the C++ code:

int main(){
    M* m;

    O* o = new IO();
    H* h = new H("A");

    if(__rdtsc() % 5 == 0){
        m = new Y(o, h);
    }
    else{
        m = new Z(o, h);
    }

    m->my_virtual();

    return 1;
}

where the virtual call is represented by this asm:

mov         rax,qword ptr [x]  
mov         rax,qword ptr [rax]  
mov         rcx,qword ptr [x]  
call        qword ptr [rax]

It is one more line than I was expecting for the vtable method invoccation. Are all four of the ASM lines specific to the polymorphic call?

How do the above four lines read pseudo-ly?

This is the complete ASM and C++ (the virtual call is made right at the end):

int main(){
 add         byte ptr [rax-33333334h],bh  
 rep stos    dword ptr [rdi]  
 mov         qword ptr [rsp+0A8h],0FFFFFFFFFFFFFFFEh  
    M* x;

    o* o = new IO();
 mov         ecx,70h  
 call        operator new (013F6B7A70h) 
 mov         qword ptr [rsp+40h],rax  
 cmp         qword ptr [rsp+40h],0  
 je          main+4Fh (013F69687Fh)  
 mov         rcx,qword ptr [rsp+40h]  
 call        IO::IO (013F6814F6h)  
 mov         qword ptr [rsp+0B0h],rax  
 jmp         main+5Bh (013F69688Bh)  
 mov         qword ptr [rsp+0B0h],0  
 mov         rax,qword ptr [rsp+0B0h]  
 mov         qword ptr [rsp+38h],rax  
 mov         rax,qword ptr [rsp+38h]  
 mov         qword ptr [o],rax  
    H* h = new H("A");
 mov         ecx,150h  
 call        operator new (013F6B7A70h)  
 mov         qword ptr [rsp+50h],rax  
 cmp         qword ptr [rsp+50h],0  
 je          main+0CEh (013F6968FEh)  
 lea         rax,[rsp+58h]  
 mov         qword ptr [rsp+80h],rax  
 lea         rdx,[ec_table+11Ch (013F7C073Ch)]  
 mov         rcx,qword ptr [rsp+80h]  
 call        std::basic_string<char,std::char_traits<char>,std::allocator<char> >::basic_string<char,std::char_traits<char>,std::allocator<char> > (013F681104h)  
 mov         qword ptr [rsp+0B8h],rax  
 mov         rdx,qword ptr [rsp+0B8h]  
 mov         rcx,qword ptr [rsp+50h]  
 call        H::H (013F6826A3h)  
 mov         qword ptr [rsp+0C0h],rax  
 jmp         main+0DAh (013F69690Ah)  
 mov         qword ptr [rsp+0C0h],0  
 mov         rax,qword ptr [rsp+0C0h]  
 mov         qword ptr [rsp+48h],rax  
 mov         rax,qword ptr [rsp+48h]  
 mov         qword ptr [h],rax  

    if(__rdtsc() % 5 == 0){
 rdtsc  
 shl         rdx,20h  
 or          rax,rdx  
 xor         edx,edx  
 mov         ecx,5  
 div         rax,rcx  
 mov         rax,rdx  
 test        rax,rax  
 jne         main+175h (013F6969A5h)  
        x = new Y(o, h);
 mov         ecx,18h  
 call        operator new (013F6B7A70h)  
 mov         qword ptr [rsp+90h],rax  
 cmp         qword ptr [rsp+90h],0  
 je          main+14Ah (013F69697Ah)  
 mov         r8,qword ptr [h]  
 mov         rdx,qword ptr [o]  
 mov         rcx,qword ptr [rsp+90h]  
 call        Y::Y (013F681B4Fh)  
 mov         qword ptr [rsp+0C8h],rax  
 jmp         main+156h (013F696986h)  
 mov         qword ptr [rsp+0C8h],0  
 mov         rax,qword ptr [rsp+0C8h]  
 mov         qword ptr [rsp+88h],rax  
 mov         rax,qword ptr [rsp+88h]  
 mov         qword ptr [x],rax  
    }
    else{
 jmp         main+1DCh (013F696A0Ch)  
        x = new Z(o, h);
 mov         ecx,18h  
 call        operator new (013F6B7A70h)  
 mov         qword ptr [rsp+0A0h],rax  
 cmp         qword ptr [rsp+0A0h],0  
 je          main+1B3h (013F6969E3h)  
 mov         r8,qword ptr [h]  
 mov         rdx,qword ptr [o]  
 mov         rcx,qword ptr [rsp+0A0h]  
 call        Z::Z (013F68160Eh)  
 mov         qword ptr [rsp+0D0h],rax  
 jmp         main+1BFh (013F6969EFh)  
 mov         qword ptr [rsp+0D0h],0  
 mov         rax,qword ptr [rsp+0D0h]  
 mov         qword ptr [rsp+98h],rax  
 mov         rax,qword ptr [rsp+98h]  
 mov         qword ptr [x],rax  
    }

    x->my_virtual();
 mov         rax,qword ptr [x]  
 mov         rax,qword ptr [rax]  
 mov         rcx,qword ptr [x]  
 call        qword ptr [rax]  

    return 1;
 mov         eax,1  
}
like image 842
user997112 Avatar asked Dec 16 '22 00:12

user997112


1 Answers

You're probably looking at unoptimized code:

mov         rax,qword ptr [x]       ; load rax with object pointer
mov         rax,qword ptr [rax]     ; load rax with the vtable pointer
mov         rcx,qword ptr [x]       ; load rcx with the object pointer (the 'this' pointer)
call        qword ptr [rax]         ; call through the vtable slot for the virtual function
like image 173
Michael Burr Avatar answered Dec 17 '22 14:12

Michael Burr