【.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. ...
随机推荐
- ps、grep和kill联合使用杀掉进程
例如要杀掉hello这个进程,使用下面这个命令就能直接实现. ps -ef |grep hello |awk '{print $2}'|xargs kill -9 这里是输出ps -ef |gre ...
- Ninja Blocks物联网平台简介
Ninja Blocks是一个物联网控制平台,其平台架构包括硬件层.处理器层.软件层以及平台层,请看下图: 最底层是硬件层,包括传感器(Sensors)和驱动器(Actuators),例如温度传感器. ...
- Linux环境安装jdk
Linux中JDK1.6的安装和配置方法 一.安装 创建安装目录,在/usr/java下建立安装路径,并将文件考到该路径下: # mkdir /usr/java 1.jdk-6u11-linux-i5 ...
- mysql查看被锁住的表,正在进行的进程,已经杀掉进程的方法
mysql查看被锁的进程 //查看所有进程show processlist; //查询是否锁表show OPEN TABLES where In_use > 0; //查看被锁住的 SELECT ...
- 2014 Hangjs 见闻流水账第一天
前言 6月21日~6月22日, 第一次跑远门去参加一个大会(广州 -> 杭州),本来打算,在火车的回来的路上,把这两天的东西记录一下,不过,火车上的环境实在恶劣,同时也高估了自己的专注力,所以, ...
- Visual Studio 2013 prerequisites
http://www.visualstudio.com/zh-cn/products/visual-studio-ultimate-with-msdn-vs#Fragment_SystemRequir ...
- Linux之crontab
一 cron crond位于/etc/rc.d/init.d/crond 或 /etc/init.d 或 /etc/rc.d /rc5.d/S90crond,最总引用/var/lock/subsys ...
- 【转】Objective-C Class Dump
(转自:http://blog.sina.com.cn/s/blog_4431c7610100x15t.html) class dump是一个命令行工具,用来监测存储在Mach-O二进制文件理的Obj ...
- 【转帖】ECLIPSE-JEE-LUNA-SR2官方汉化教程
ECLIPSE-JEE-LUNA-SR2官方汉化教程 工具/原料 Eclipse-jee-luna-SR2 步骤/方法 1.在浏览器输入网址http://www.eclipse.org/babel/d ...
- 菜鸟教程之工具使用(十四)——Maven项目右击没有“Maven”菜单选项
从Git导入一个Maven项目,右击想更新Maven引用的jar包,却发现右键菜单根本没有“Maven”菜单项.怎么办?很简单,按如下步骤操作即可: 从Git导入后,右击项目没有“Maven”菜单项: ...