What is the assembly equivalent of C++ function overloading?
As @n.pronounsm. and several others said in the comments, each separate function overload is given a special name in assembly by the compiler. This names encodes both the function name and the parameter types. Thus different function overloads are distinguished in assembly, both when declared and when called.
TL:DR: overloading is basically a source-level thing that makes the arg types part of the function name. Theres no real equivalent in hand-written asm. Asm doesnt even have a type system; its up to you to use sensible instructions that do something useful with the bit-patterns in registers.
C++ compilers implement it in asm by using name mangling so the asm symbol name for
foo(int, int) is for example
_Z3fooii. (Godbolt compiler explorer).
Function overloading in C++ is statically resolved at compile time. No function pointers or any other runtime shenanigans are involved.
It effectively makes the types of the args part of the function name. So for hand-written asm, the equivalent could be some simple manual scheme like
foo_int_int, etc. Each with a separate definition, exactly like 3 separate functions with totally different names.
C++ enables much more code-reuse (especially via templates) than asm. You could imagine trying to do something in asm with macros, where maybe you have a macro arg thats a string like
int or something. But unless the macro only stitches together calls to other functions (by tacking on the string to some base-name, like
call foo_%1 /
mov rdi, rax /
call bar_%1), this doesnt really work in asm (because each instruction doing real work has to use registers of the right size).
I guess maybe for a macro that takes register names as macro parameters, it could expand to
add rax, rsi or
add eax, esi depending on what the caller passed, and it could pass
int to match. (So the macro is like a template function with the type as a template param; the overloading is just in the calls that use the type name as part of the asm symbol name.) That can of course only work in limited circumstances. e.g.
float needs different mnemonics than
long as well as different register names, on most ISAs.