【.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. ...
随机推荐
- 移动APP的IM后台架构浅析
IM(InstantMessaging 即时通讯)作为一项基础功能,很多APP都有,比如:手机QQ.微信.易信.钉钉.飞信.旺旺.咚咚.陌陌等.而IM如同我们日常生活中的水和电一样,必不可少,也是很多 ...
- A Xamarin.Forms Infinite Scrolling ListView
from:http://www.codenutz.com/lac09-xamarin-forms-infinite-scrolling-listview/ The last few months ha ...
- js for in对象key排序
最近遇到一个比较奇葩的事情,for in 循环的时候,如果对象key 默认可以转化为整数,会把key转化为整数排序. code: 运行结果 大家看到data2的key默认顺序是"2" ...
- 那些在学习iOS开发前就应该知道的事(part 1)
英文原文:Things I wish I had known before starting iOS development—Part 1 http://www.cocoachina.com/ios/ ...
- 使用Installutil安装系统服务方法
系统必须装有.net Framework2.0然后点击开始-运行输入以下指令即可完成相应操作安装服务:C:/WINDOWS/Microsoft.NET/Framework/v2.0.50727/Ins ...
- 是时候放弃sublime了
今天下午在忍无可忍之下终于卸载了sublime,最为一个在gui下最顺手的编辑器,放弃是需要非常充足的理由的. 放弃sublime无非是因为以下几点原因: 收费.我用的是未注册版的sublime,保存 ...
- 使用jQuery页面加载函数启动定时任务
var timer; $(document).ready(function(){ if (timer == undefined) timer = window.setInterval(showTime ...
- R语言之中文分词:实例
一.说明 网上提供的一个例子,做了修改与订正. 二.程序 #调入分词的库 library("rJava") library("Rwordseg") #调入绘制词 ...
- Erwin 生成 mysql 带注释(comment )的脚本
Erwin设计数据库非常方便,有逻辑视图和物理视图,可以很方便的生成数据库文档和SQL 脚本.在使用过程中唯一不爽的地方是脚本不能生成comment. 在百度无数次无法解决下,又FQ谷歌,在一个日 ...
- 修改eclipse启动时eclipse使用的jre
eclipse在启动的时候,和环境变量中的jdk不兼容,可以单独制定eclipse运行的jre. 方法: 在eclipse的配置文件里增加-vm参数即可. 打开eclipse目录下的eclipse.i ...