【.Net底层剖析】2.stfld指令-给对象的字段赋值
2.【.Net底层剖析】2.stfld指令-给对象的字段赋值
引言:
这篇我们讲解在.net IL中间语言中,经常见到的指令stfld。
该指令经常用在给一个对象的字段赋值。
一、指令用途:
MSDN解释如下:
Replaces the value stored in the field of an object reference or pointer with a new value.
翻译过来就是:用一个新值替换对象字段的值
二、命名空间和程序集
命名空间是在 System.Reflection.Emit这个里面
程序集是mscorlib(mscorlib.dll中)
三、指令执行机制
工作原理即堆栈转换行为如下:
按照先后顺序:
1.将一个对象引用或指针压入堆栈
2.将值被压入堆栈
3.该值和对象的引用/指针从堆栈中弹出,对象的字段更新为替换的值
四、 实例代码分析:
C#程序:
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
Test test1=new Test();//new一个Test对象
test1.i = ;//将Test对象的字段i赋值为12
} /// <summary>
/// 测试类
/// </summary>
public class Test
{
public int i = ;
}
}
}
IL 程序Main方法
.method private hidebysig static void Main(string[] args) cil managed
{
.entrypoint
// Code size (0x10)
.maxstack
.locals init ([] class ConsoleApplication1.Program/Test test1)
IL_0000: nop
IL_0001: newobj instance void ConsoleApplication1.Program/Test::.ctor()
IL_0006: stloc.
IL_0007: ldloc.
IL_0008: ldc.i4.s
IL_000a: stfld int32 ConsoleApplication1.Program/Test::i
IL_000f: ret
} // end of method Program::Main
我们来逐行分析下main方法的IL代码
.entrypoint //定义函数的入口点
// Code size 16 (0x10)//代码大小为16
.maxstack 2//栈的大小为2
.locals init ([0] class ConsoleApplication1.Program/Test test1)//定义一个变量为test1,存储在<本地变量列表>中第一个变量中
IL_0000: nop//空操作
IL_0001: newobj instance void ConsoleApplication1.Program/Test::.ctor()//new 一个Test对象,一个引用指向这个对象,引用存放在栈上,
对象存放在堆上面
IL_0006: stloc.0//将引用弹栈,存放到<本地变量列表>中的第一个变量中
IL_0007: ldloc.0//将<本地变量列表>中第一个变量的值压入堆栈
IL_0008: ldc.i4.s 12//将int 12压入堆栈
IL_000a: stfld int32 ConsoleApplication1.Program/Test::i//将堆栈的栈顶的值赋值给堆栈的第二个值,即test.i=12
IL_000f: ret//函数返回
五、内存分析
在指令stfld 执行之前的内存图

堆栈中存放12,test1的地址,<本地变量列表>第一个变量中存放的是test1的地址,堆中存放的是test1指向的一个对象,其中test1.i=100
在指令stfld 执行之后的内存图

堆栈中的12,test1的地址弹出,<本地变量列表>第一个变量中存放的是test1的地址不变,堆中存放的是test1.i=12
六、总结
本篇主要讲的就是对象的字段如何在内存中是如何赋值的,以及从每一行IL指令分析stfld 的执行过程。从底层分析对象的字段的赋值,可以更加清晰地看到赋值的过程。
下篇我会从.net底层剖析参数的传递,有兴趣的可以关注我哦!
【.Net底层剖析】2.stfld指令-给对象的字段赋值的更多相关文章
- 【.Net底层剖析】3.用IL来理解属性
.Net底层剖析目录章节 1.[深入浅出.Net IL]1.一个For循环引发的IL 2.[.Net底层剖析]2.stfld指令-给对象的字段赋值 3.[.Net底层剖析]3.用IL来理解属性 未完待 ...
- .Net底层剖析目录章节
[.Net底层剖析]目录章节 1.[深入浅出.Net IL]1.一个For循环引发的IL 2.[.Net底层剖析]2.stfld指令-给对象的字段赋值 3.[.Net底层剖析]3.用IL来理解属性 作 ...
- 底层剖析Python深浅拷贝
底层剖析Python深浅拷贝 拷贝的用途 拷贝就是copy,目的在于复制出一份一模一样的数据.使用相同的算法对于产生的数据有多种截然不同的用途时就可以使用copy技术,将copy出的各种副本去做各种不 ...
- js对象详解(JavaScript对象深度剖析,深度理解js对象)
js对象详解(JavaScript对象深度剖析,深度理解js对象) 这算是酝酿很久的一篇文章了. JavaScript作为一个基于对象(没有类的概念)的语言,从入门到精通到放弃一直会被对象这个问题围绕 ...
- JS面向对象(2) -- this的使用,对象之间的赋值,for...in语句,delete使用,成员方法,json对象的使用,prototype的使用,原型继承与原型链
相关链接: JS面向对象(1) -- 简介,入门,系统常用类,自定义类,constructor,typeof,instanceof,对象在内存中的表现形式 JS面向对象(2) -- this的使用,对 ...
- Emit动态生成代理类用于监控对象的字段修改
利用Emit动态生成代理对象监控对象哪些字段被修改,被修改为什么值 被Register的对象要监控的值必须是Virtual虚类型 必须使用CreateInstance创建对象 必须使用DynamicP ...
- 007-Scala类的属性和对象私有字段实战详解
007-Scala类的属性和对象私有字段实战详解 Scala类的使用实战 变量里的类必须赋初值 def函数时如果没参数可不带括号 2.不需要加Public声明 getter与setter实战 gett ...
- [转]Hibernate查询对象所有字段,单个字段 ,几个字段取值的问题
原文地址:http://www.ablanxue.com/prone_3552_1.html 1. 查询整个映射对象所有字段 Java代码 //直接from查询出来的是一个映射对象,即:查询整个映射对 ...
- runtime使用小例子 - 给对象O-C属性赋值
这些日子在家里学习runtime,看runtime的一些方法和前辈们的博客,我也尝试着写几个runtime有效的运用 一.给对象属性赋值,例如一个WebEntity类 她有三个属性:NSString. ...
随机推荐
- Struts2学习笔记-jsp中引用struts2框架
如果在jsp中需要引用struts2 框架,需在前面加上以下内容 <%@taglib prefix="s" uri="/struts-tags" %> ...
- I2S (Inter—IC Sound) 总线
I2S I2S(Inter—IC Sound)总线, 又称 集成电路内置音频总线,是飞利浦公司为数字音频设备之间的音频数据传输而制定的一种总线标准,该总线专责于音频设备之间的数据传输,广泛应用于各种多 ...
- 制作6寸 kindle pdf
设置word 纸张大小为 90mm*117mm 然后保存为 pdf 就好了.
- android 常用小功能(第二版)
经历过一段岁月,转眼2013的半年都过去了,第二版整理好的小功能,答应大家发布的,直到今日,终于和大家相见了,第二版没有第一版多,大家也可以去参考第一版的内容,希望大家使用愉快! 目录: 1.获取当前 ...
- Asp.net Core 使用Redis存储Session
前言 Asp.net Core 改变了之前的封闭,现在开源且开放,下面我们来用Redis存储Session来做一个简单的测试,或者叫做中间件(middleware). 对于Session来说褒贬不一, ...
- Web service standards: SOAP, REST, OData, and more
Web service standards: SOAP, REST, OData, and more So far, we've covered the components of a web ser ...
- 第一章:Symfony2和HTTP基本原理
恭喜你!通过学习Symfony2,你将用你自己的方式开发出更加高效.全面和流行的Web应用(当然,要受到用人单位或同行的欢迎,还是得靠你自己).Symfony2的存在是为了要解决最根本的问题:即提供一 ...
- floor相关
select floor(@f*0.22) -- 直接可显示结果 create table demo( id ,), id1 int ) select * from demo insert into ...
- mac或linux下xampp的mysql配置
在mac 下安装好xampp后,需要在终端命令行操作时,比如输入:mysql -u root -p,未正确配置前不会出现想要的输入密码提示,而是会提示: command not found 原来当你输 ...
- volley中图片加载
volley图片加载有三种方式: 记得:Volley中已经实现了磁盘缓存了,查看源码得知通过 context.getCacheDir()获取到了 /data/data/<application ...