One : background
1. An interesting topic
Recently in to see Hardware exception Related knowledge , Found an interesting null reference exception problem , Take it out and share it with you , For the convenience of narration , Let's start with a problematic code .
namespace ConsoleApp2
{
internal class Program
{
static Person person = null;
static void Main(string[] args)
{
var age = person.age;
Console.WriteLine(age);
}
}
public class Person
{
public int age;
}
}
because person It's a null object , Obviously this code throws exceptions , So why throw exceptions ? To find out why , You need to start with the lowest level of assembly .
Two : Abnormal principle analysis
1. Look for the answer from the compilation
have access to Visual Studio 2022 Disassembly window for , Observe var age = person.age; What exactly is generated at .
---------------- var age = person.age; ----------------
081D6154 mov ecx,dword ptr ds:[4C41F4Ch]
081D615A mov ecx,dword ptr [ecx+4]
081D615D mov dword ptr [ebp-3Ch],ecx
These three sentences are easy to understand ,4C41F4Ch Deposit is person object , ecx+4 Is to take person.age, The last sentence is to age Put it in ebp-3Ch Stack position , Let's take a look at null At the time of the ecx How much is it , The screenshot is as follows :

As you can see from the diagram , At this time ecx=0000000, If you know windows Virtual memory layout , You should know that in the virtual memory 0~0x0000ffff The scope belongs to null Exclusion zone , Anyone who falls in this area is a visit violation , Draw a picture like this .

The principle will be clear here , because [ecx+4] = [4] It fell on this null Area caused , however .... Have you found a problem , Yes , It's here [ecx+4], Because there's a +4 Offset to get age Field , Can I just person Define more fields in , Then take the last field from null District Rush out ... ha-ha .
2. Can really rush out null District
With this idea , I've decided to Person Definition in class 10w individual age Field , The reference codes are as follows :
namespace ConsoleApp2
{
internal class Program
{
static Person person = null;
static void Main(string[] args)
{
var str = @"public class Person
{
{0}
}";
var lines = Enumerable.Range(0, 100000).Select(m => $"public int age{m};");
var fields = string.Join("\n", lines);
var txt = str.Replace("{0}", fields);
File.WriteAllText("Person.cs", txt);
Console.WriteLine("person.cs Generation completed ");
}
}
}
After code execution ,Person.cs Will be generated as scheduled , Next read person.age99999 See if miracles happen , The reference codes are as follows :
internal class Program
{
static Person person = null;
static void Main(string[] args)
{
var age = person.age99999;
Console.WriteLine(age);
}
}

I went to , Never in my wildest dreams , hold ClassLoader It broke up .... have to , That can only be changed 20000 individual age Have a try. , The reference codes are as follows :
internal class Program
{
static Person person = null;
static void Main(string[] args)
{
var age = person.age19999;
Console.WriteLine(age);
}
}
Next, we put the breakpoint in var age = person.age19999; Continue to look at disassembly code .
------------- var age = person.age19999; -------------
0804657E mov ecx,dword ptr ds:[49F1F4Ch]
08046584 mov dword ptr [ebp-40h],ecx
08046587 mov ecx,dword ptr [ebp-40h]
0804658A cmp dword ptr [ecx],ecx
0804658C mov ecx,dword ptr [ebp-40h]
0804658F mov ecx,dword ptr [ecx+13880h]
08046595 mov dword ptr [ebp-3Ch],ecx
From the assembly code above, we can see some information .
There are too many lines of assembly code .
ecx+13880h Out null District (FFFF) The boundary of the .
Next, step through the assembly , Found in cmp dword ptr [ecx],ecx An exception was thrown at ...

We all know that at this time ecx The address is 0 , from ecx Fetching content will definitely throw access violations , And this code is weird , Generally speaking cmp After that, it is similar jz,jnz Jump instruction , And it is only a half broken sentence ...
From these characteristics , This is a JIT Deliberately try to judge before taking the offset ecx Is it right? null, The motive is not pure ....
3、 ... and : summary
From these analyses we can see that ,JIT Still very intelligent .
When the offset value falls at
0~FFFFNo entry zone ,JIT No judgment code is generated to reduce the code volume .At the offset value, the
0~FFFFExclusion zone ,JIT Have to generate code to judge .
ha-ha , Is this article very interesting , Hopefully that helped .








