【.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. ...
随机推荐
- android 给空白包签名
前言:之前公司app在腾讯开放平台认领应用时,涉及了一个问题:就是给空白包签名.然后再上传上去审核. 腾讯开放平台的官方说明如下, 如何签名:jarsgner-verbose-keystore[key ...
- 在eclipse中安装freemarker插件及html使用freemarker编辑器
freemarker模板文件使用jboss tools下提供的FreeMarker IDE,在线安装的方法是:Help –> Install New Software 点击and,再出来的对话框 ...
- 学javascript必须要知道的事
第一:变量声明 在使用javascript时使用变量时首先做的是声明变量,变量声明的关键字是var. 例子: var i; var sum; 也可以多个变量声明: var i,sum; 还可以在声明时 ...
- 【转】iOS 10 UserNotifications 使用说明
注意:XCode8的需要手动开启主target Capabilities中的Push Notification. 关于创建多个target后真机测试的证书问题,除了主target手动创建开发和发布证书 ...
- 让input支持 ctrl v上传粘贴图片? 让input支持QQ截图或剪切板中的图像数据(Java实现保存)
原理:监听粘贴 → 获取粘贴内容 → 将内容上传 → 抓取后返回替换至input 我们在生产中用到的界面: 测试地址 http://sms.reyo.cn 用户名:aa 密码:123456 以下是PH ...
- Android屏幕适配的一些常识
屏幕适配的注意事项 1. AndroidManifest.xml设置 在中Menifest中添加子元素 android:anyDensity="true"时,应用程序安装在不同密度 ...
- [Aaronyang] 写给自己的WPF4.5 笔记20 [3d课 1/4]
假设你是高中毕业的,ok,数学知识几何知识中,我们学过 x,y,z 3个轴然后就可以画出形状了. 1. 新建空白窗体,grid换成canvas,然后新增一个Viewport3D元素 3d中显示的 ...
- ubuntu 休眠之后网络间接失败 can not connect to network after suspend (wake up)
ubuntu for laptop系统在系统休眠后wakeup 之后,网络连接失败, 有线网络无法连接, 无线wifi无法连接, 只能重启后才能恢复, 此时可以采用以下方法处理: 1. 在/etc/p ...
- 自己写的一个Yeoman的Generator-Require-Angularjs
Yeoman是一个常见的工作流,能够很方面的搭建属于自己的脚手架. 这段时间我用闲暇时间写了一个Generator来玩了一下,这个Generator的主要目的是快速建立一个RequireJS+Angu ...
- 利用cmdline和gradle快速编译出apk
http://blog.csdn.net/qq_16628781/article/details/49365139 gradlew.bat clean build --info > bugtag ...