This is from 64-bit Linux shared object:
mov rax, [rbp+var_1C+4]
mov rax, [rax]
add rax, 8
mov rax, [rax]
mov rdx, [rbp+var_1C+4]
mov rdi, rdx
call rax
Looks like a virtual function call.
Looks like un-optimized compiler output, given the usage of rbp
as a frame pointer, and using add rax,8
instead of an addressing mode like mov rax, [rax+8]
. And the reload of the local for no reason when it could have kept the pointer live in a register after loading it earlier.
It looks like it's preparing a this
pointer as an arg for the virtual function, as well as calling a virtual function through the vtable. How do objects work in x86 at the assembly level?
Anyway this code is just an inefficient way of writing
mov rdi, [rbp+var_1C+4] # load a pointer to a local from the stack
mov rax, [rdi] # load the vtable pointer from the start of the object
call [rax+8] # index into the vtable
Or maybe setting rdx
was intended, rather than just inefficient un-optimized code. In the x86-64 System V ABI, rdx
holds the 3rd integer / pointer arg to function calls. rdi
holds the first (including this
as a hidden first arg). If rsi
was set earlier, then perhaps rdx
is being passed intentionally, so it's a call like foo->virtual_function(something, foo)
, where class something *foo
is a local variable or function arg.
Otherwise it's just foo->virtual_function()
.
Or it's something completely different that just happens to look like what a compiler would emit for a virtual function call. You can't know without more context.