当前位置:网站首页>Talk about the bottom playing method of C # method overloading
Talk about the bottom playing method of C # method overloading
2022-06-13 09:44:00 【Dotnet cross platform】
Recently in to see C++ Method overload , I was thinking. C# How to play the overloaded bottom layer in , A lot of friends should know C Overloading is not supported , For example, the following code will report an error .
#include <stdio.h>
int say() {
return 1;
}
int say(int i) {
return i;
}
int main()
{
say(10);
return 0;
}
From the error message , It said say Methods already exist , embarrassed ...
One : Why? C I won't support it
To find the answer , Need to know a little bit of the underlying knowledge , That is, the compiler is compiling C Method will Function name Add as symbol to The symbol table in , This The symbol table Namely call To say Method bytecode A carrier in the middle , Draw a picture, that's about it .

In short ,call Jump to the first The symbol table , And then again jmp To say Method , Here's the problem , The symbol table Is a kind of dictionary structure , Can't appear Symbol The same thing . by the way , stay windbg We can use x Command to search for these symbols ,
To prove my point , You can verify it at the assembly level , Modify the code as follows :
#include <stdio.h>
int say(int i) {
return i;
}
int main()
{
say(10);
return 0;
}Next, let's look at the compilation .
--------------- say(10) -----------
00C41771 push 0Ah
00C41773 call _say (0C412ADh)
--------------- The symbol table -----------
00C412AD jmp say (0C417B0h)
--------------- say body -----------
00C417B0 push ebp
00C417B1 mov ebp,esp
00C417B3 sub esp,0C0h
00C417B9 push ebx
00C417BA push esi
00C417BB push edi
00C417BC mov edi,ebp
00C417BE xor ecx,ecx
00C417C0 mov eax,0CCCCCCCCh
00C417C5 rep stos dword ptr es:[edi]
00C417C7 mov ecx,offset [email protected] (0C4C008h)
... After knowing the principle , Let's see C++ How is the The symbol table To achieve a unique breakthrough .
Two :C++ Symbol table breakthrough
For the convenience of narration , Let's start with a paragraph C++ Method overloaded code .
using namespace std;
class Person
{
public:
void sayhello(int i) {
cout << i << endl;
}
void sayhello(const char* c) {
cout << c << endl;
}
};
int main(int argc)
{
Person person;
person.sayhello(10);
person.sayhello("hello world");
} Logically speaking sayhello There are many. , There must be no breakthrough , With curiosity, let's take a look at its disassembly code .
---------- person.sayhello(10); ----------------
003B2E5F push 0Ah
003B2E61 lea ecx,[person]
003B2E64 call Person::sayhello (03B13A2h)
------------ person.sayhello("hello world"); ----------------
003B2E69 push offset string "hello world" (03B9C2Ch)
003B2E6E lea ecx,[person]
003B2E71 call Person::sayhello (03B1302h) From the perspective of assembly code , All of them Person::sayhello This symbol , Strangely, they belong to different addresses : 03B13A2h, 03B1302h, This is so strange , ha-ha , Dictionary class symbol table There must be no problem , The problem is Visual Studio 20222 The Disassembly window does some internal conversion during debugging , It has blinded our eyes ,
It's really annoying !!! Even the runtime assembly code is not thorough enough , Now how can we continue to dig ? It can be used IDA Go and see the program Static disassembly code , The screenshot is as follows :

You can clearly see from the comments on the code , original :
Person::sayhello(int)Turned into[email protected]@@[email protected].Person::sayhello(char const *)Turned into[email protected]@@[email protected]
Here we finally find out , original C++ To support method overloading , take Method name Recoded , This can really break through The symbol table The uniqueness limit of .
3、 ... and :C# How to achieve breakthrough
We all know C# The bottom of the CLR By C++ Written , So the big probability game is the same , Next, the previous code :
internal class Program
{
static void Main(string[] args)
{
// Make a deliberate repetition
Say(10);
Say("hello world");
Say(10);
Say("hello world");
Console.ReadLine();
}
static void Say(int i)
{
Console.WriteLine(i);
}
static void Say(string s)
{
Console.WriteLine(s);
}
} because C# The method is by JIT Dynamically compiled at run time , And the first compilation method will jump to JIT Pile address of , So the breakpoint must be placed on the second call Say(10) To see the symbolic address of the method , The assembly code is as follows :
----------- Say(10); -----------
00007FFB82134DFC mov ecx,0Ah
00007FFB82134E01 call Method stub for: ConsoleApp1.Program.Say(Int32) (07FFB81F6F118h)
00007FFB82134E06 nop
----------- Say("hello world"); -----------
00007FFB82134E07 mov rcx,qword ptr [1A8C65E8h]
00007FFB82134E0F call Method stub for: ConsoleApp1.Program.Say(System.String) (07FFB81F6F120h)
00007FFB82134E14 nopFrom the output information , Also two symbol table addresses , Then the symbol table addresses jmp To the last method body .
----------- Say(10); -----------
00007FFB82134E01 call Method stub for: ConsoleApp1.Program.Say(Int32) (07FFB81F6F118h)
----------- The symbol table -----------
00007FFB81F6F118 jmp ConsoleApp1.Program.Say(Int32) (07FFB82134F10h)
----------- Say body -----------
00007FFB82134F10 push rbp
00007FFB82134F11 push rdi
00007FFB82134F12 push rsi
00007FFB82134F13 sub rsp,20h
00007FFB82134F17 mov rbp,rsp
00007FFB82134F1A mov dword ptr [rbp+40h],ecx
00007FFB82134F1D cmp dword ptr [7FFB82036B80h],0
00007FFB82134F24 je ConsoleApp1.Program.Say(Int32)+01Bh (07FFB82134F2Bh)
00007FFB82134F26 call 00007FFBE1C2CC40 I don't know how to look at it yet JIT After the change of name Method name , You can leave a message if you know , But on the whole it's still C++ A set of .
OK, that's all for this article , I hope it helps you .
边栏推荐
猜你喜欢
![[Luogu p1403] Research on divisor](/img/c1/b2a91ddad264d5f8283abf27dc8839.jpg)
[Luogu p1403] Research on divisor
![[51nod p2673] shortest path [heap optimization Dijk]](/img/08/5e68466fe8ff8458f736bc50d897da.jpg)
[51nod p2673] shortest path [heap optimization Dijk]

acwing 790. The third root of a number (dichotomy)
![[pytorch environment installation]](/img/00/78f6942ed3ff721675abb91504fb5c.png)
[pytorch environment installation]

The turtle library displays the system time

Consolas-with-Yahei

(tree DP) acwing 285 A dance without a boss

go-zero微服务实战系列(三、API定义和表结构设计)

一篇文章读懂:Spark运行模式

Tree and binary tree: basic operation and implementation of binary tree
随机推荐
Standard template library (STL)
Node-RED系列(二五):集成高德地图并实现3d地图和轨迹回放
Biden: hope to sign the bipartisan gun safety reform bill as soon as possible
多线程 从UE4的无锁队列开始 (线程安全)
递归想法和实现介绍,消除递归
类文件结构和类加载过程执行引擎简述
Pxxx local socket communication
云计算企业崛起 甲骨文数据库市场主导地位动摇
(dfs) acwing 842. Arrange numbers
MySQL利用E-R模型的数据库概念设计
LeetCode 322. Change
[51nod p2653] interval XOR [bit operation]
Execution order of subclass and parent constructor
(state compression dp+ binary) acwing 91 Shortest Hamilton path
(bfs+GOOD) acwing 845. Eight digit
六月集训(第13天) —— 双向链表
Trees and binary trees: Construction of binary trees
MySQL monitoring tool PMM, let you go to a higher level (Part 2)
[Luogu p1090, ssl1040] merged fruit [pile]
7-3 virus traceability (20 points)