IL指令笔记:

1.newObj和initObj

MSDN解释:newObj用于分配和初始化对象,而initObj用户初始化值类型

newObj解释:

(1):从托管堆分配指定类型所需要的全部内存空间

(2):在调用执行构造函数初始化之前,首先初始化对象的附加成员,一个是指向该类型方法表的指针,一个是SyncBlockIndex,用于进行线程

的同步,所有的对象都包含这俩个附加成员,用于管理对象.

(3):最后才是调用构造函数ctor,进行初始化操作,并返回新建对象的引用地址.

initObj:

(1):构造新的值类型,完成值类型初始化,值得关注的是,这种构造不需要调用值类型的构造函数.

(2):initObj还用于完成设定对指定存储单元的指针置空(null),这一操作虽不常见,但是应该引起注意.

由此可见,newObj和initObj,都具有完成实例初始化的功能,但是针对的类型不同,执行的过程有异,其区别:

(1):newObj用于分配和初始化对象,而initObj用于初始化值类型.因此,可以说,newObj在堆中分配内存,并完成初始化.

而initObj则是对栈上已经分配好的内存,进行初始化即可,因此值类型在编译期已经在栈上分配好了内存.

(2):newObj在初始化过程中会调用构造函数,而initObj不会调用构造函数,而是直接对实例置空

(3):newObj有内存分配的过程,而initObj则只完成数据初始化操作.

2.Newarr

Newarr指令用来创建一维从零起始的数组;而多维或非从零起始的一维数组,则仍由newobj指令创建

3.ldstr

String类型的创建由ldstr指令来完成.

4.call,callvirt和calli

call : 使用静态调度,也就是根据引用类型的静态类型来调度方法.(主要负责调用静态方法)

callvirt: 使用虚拟调度,也就是根据引用类型的动态类型来调度方法.(主要负责调用实例方法)

calli:又称间接调用,是通过函数指针来执行方法调用;对应的直接调用当然就是前面的"call和callvirt

5. .assembly

.assembly指令用于定义编译目标或者加载外部库

6. .hash algorithm指令:表示实现安全性所使用的哈希算法;系统缺省为0x00008004,表明为SHA1算法,.ver则表示HelloWord程序集的版本号

7..module为程序集指令,表明定义的模块的元数据,以指定当前模块.

8. imagebase为影像基地址,.file alignment为文件对齐数值;.subsystem为连接系统类型;0x003表示从控制台运行;.cortflags为设置运行库头文件标志,

默认为1.

9.实例解析

.class public auto ansi beforefieldinit HelloWorld extends [mscorlib]System.Object { } //

IL代码解析:

.class表明了Hello World是一个public类,该类继承自外部程序集mscorlib的System.Object类.

public为访问控制权限

auto表明程序加载时内存的布局是由CLR决定的,而不是程序本身

ansi属性则为了在没有被管理和被管理代码间实现无缝转换。没有被管理的代码,指的是没有运行在CLR运行库之上的代码,例如原来的C,C++代码等。

beforefieldinit属性为HelloWorld提供了一个附加信息,用于标记运行库可以在任何时候执行类型构造函数方法,只要该方法在第一次访问其静态字段之前执行即可。如果没有beforefieldinit则运行库必须在某个精确时间执行类型构造函数方法,从而影响性能优化,详细的情况可以参与MSDN相关内容。

然后是.ctor方法,代码为:

.method public hidebysig specialname rtspecialname instance void .ctor() cil managed {

// 代码大小 7 (0x7)

.maxstack 8

IL_0000: ldarg.0

IL_0001: call instance void [mscorlib]System.Object::.ctor()

IL_0006: ret

} // end of method HelloWorld::.ctor
 cil managed 说明方法体中为IL代码,指示编译器编译为托管代码。
 .maxstack表明执行构造函数.ctor期间的评估堆栈(Evaluation Stack)可容纳数据项的最大个数。关于评估堆栈,其用于保存方法所需变量的值,并在方法执行结束时清空,或者存储一个返回值。
 IL_0000,是一个标记代码行开头,一般来说,IL_之前的部分为变量的声明和初始化。
 ldarg.0 表示装载第一个成员参数,在实例方法中指的是当前实例的引用,该引用将用于在基类构造函数中调用。
 call指令一般用于调用静态方法,因为静态方法是在编译期指定的,而在此调用的是构造函数.ctor()也是在编译期指定的;而另一个指令callvirt则表示调用实例方法,它的调用过程有异于call,函数的调用是在运行时确定的,首先会检查被调用函数是否为虚函数,如果不是就直接调用,如果是则向下检查子类是否有重写,如果有就调用重写实现,如果没有还调用原来的函数,依次类推直到找到最新的重写实现。
 ret表示执行完毕,返回。

最后是Main方法,代码为:

.method public hidebysig static void Main() cil managed

{

.entrypoint

// 代码大小 11 (0xb)

.maxstack 8

IL_0000: ldstr "Hello, world."

IL_0005: call void [mscorlib]System.Console::WriteLine(string)

IL_000a: ret

} // end of method HelloWorld::Main
 .entrypoint指令表明了CLR加载程序HelloWorld.exe时,是首先从.entrypoint方法开始执行的,也就是表明Main方法将作为程序的入口函数。每个托管程序必须有并且只有一个入口点。这区别于将Main函数作为程序入口标志。
 ldstr指令表示将字符串压栈,"Hello, world."字符串将被移到stack顶部。CLR通过从元数据表中获得文字常量来构造string对象,值得注意的是,在此构造string对象并未出现在《第五回:深入浅出关键字---把new说透》中提到的newobj指令,对于这一点的解释我们将在下一回中做简要分析。
 hidebysig属性用于表示如果当前类作为父类时,类中的方法不会被子类继承,因此HelloWorld子类中不会看到Main方法。

读<你必须知道的.NET>IL指令笔记的更多相关文章

  1. 《你必须知道的.NET》读书笔记一:小OO有大智慧

    此篇已收录至<你必须知道的.Net>读书笔记目录贴,点击访问该目录可以获取更多内容. 一.对象  (1)出生:系统首先会在内存中分配一定的存储空间,然后初始化其附加成员,调用构造函数执行初 ...

  2. 《你必须知道的.NET》读书笔记二:小OO有大原则

    此篇已收录至<你必须知道的.Net>读书笔记目录贴,点击访问该目录可以获取更多内容. 一.单一职责原则 (1)核心思想:一个类最好只做一件事,只有一个引起它变化的原因 (2)常用模式:Fa ...

  3. 《你必须知道的.NET》读书笔记三:体验OO之美

    此篇已收录至<你必须知道的.Net>读书笔记目录贴,点击访问该目录可以获取更多内容. 一.依赖也是哲学 (1)本质诠释:“不要调用我们,我们会调用你” (2)依赖和耦合: ①无依赖,无耦合 ...

  4. 《你必须知道的.NET》读书笔记:从Hello World认识IL

    通用的语言基础是.NET运行的基础,当我们对程序运行的结果有异议的时候,如何透过本质看表面,需要我们从底层来入手探索,这时候,IL便是我们必须知道的基础. 一.IL基础概念 1.1 什么是IL? IL ...

  5. C#刨根究底:《你必须知道的.NET》读书笔记系列

    一.此书到底何方神圣? <你必须知道的.NET>来自于微软MVP—王涛(网名:AnyTao,博客园大牛之一,其博客地址为:http://anytao.cnblogs.com/)的最新技术心 ...

  6. 《你必须知道的.NET》读书笔记:方法表初窥

    一.窥探准备工作 public class Base { public void M() { Console.WriteLine("M in Base"); } public vi ...

  7. 《你必须知道的.NET》读书实践:一个基于OO的万能加载器的实现

    此篇已收录至<你必须知道的.Net>读书笔记目录贴,点击访问该目录可以获取更多内容. 一.关于万能加载器 简而言之,就是孝顺的小王想开发一个万能程序,可以一键式打开常见的计算机资料,例如: ...

  8. [你必须知道的.NET]第二十四回:认识元数据和IL(上)

    发布日期:2009.02.24 作者:Anytao © 2009 Anytao.com ,Anytao原创作品,转贴请注明作者和出处. 说在,开篇之前 很早就有说说Metadata(元数据)和IL(中 ...

  9. [你必须知道的.NET]第二十六回:认识元数据和IL(下)

    发布日期:2009.03.04 作者:Anytao © 2009 Anytao.com ,Anytao原创作品,转贴请注明作者和出处. 说在,开篇之前 书接上回: 第二十四回:认识元数据和IL(上), ...

随机推荐

  1. 《图解tcp/ip》读书笔记(二)

    <图解tcp/ip>读书笔记(二) 本周主要阅读的是本书的第三章--数据链路. 当然了,从某些角度讲,我认为这一章就是计算机网络的最基本的内容之一.整章讲述了数据链路层的作用和相关技术,主 ...

  2. try-catch和throw,throws的区别和联系

    转载:http://blog.sina.com.cn/s/blog_62148d1e0100hkqc.html 区别一:throw 是语句抛出一个异常:throws 是方法抛出一个异常: throw语 ...

  3. 趋势or过渡,量子点屏幕真的优于OLED?

    [导读]谁都知道买电视就是要买看起来很爽的产品,但怎么界定这个“爽”字?大部分人所知的是屏幕要够大,再近一步就是分辨率要够高——在这个4K分辨率逐步进入寻常家庭的时代,这两者已经不是选购屏幕类产品的大 ...

  4. [codevs1283]等差子序列(二进制)

    题目:http://codevs.cn/problem/1283/ 分析: 主要就是在每个判定上节省时间.一般的做法是开个数组记录每个数字出没出现,然后每次读入一个数字就以他为中间向两边扩展直到两个对 ...

  5. 第五章:javascript:队列

    队列是一种列表,不同的是队列只能在末尾插入元素,在队首删除元素.队列用于存储按顺序排列的数据.先进先出.这点和栈不一样,在栈中,最后入栈的元素反被优先处理.可以将队列想象成银行排队办理业务的人,排队在 ...

  6. PHP微信登錄(網頁授權)之後的獲取用戶的信息

    //這部峯代碼是封裝的庫文件,<?php /** * Created by PhpStorm. * User: root * Date: 16-6-23 * Time: 下午3:29 */ cl ...

  7. 软工实践练习一(个人)----将Androidstudio的项目共享到github

    在Androidstudio上使用git插件 将项目共享至github 将 显示共享成功但是出了点问题 项目文件并没有上传至github库中,而是只创建了一个新的库 问题在于我的gitforwindo ...

  8. 详解在visual studio中使用git版本系统(图文)

    很多人已经在使用git(或正在转移到git上),在github.com上,也看到园子里不少同学的开源项目,非常不错.但相关教程似乎不多,所以趁着我自己的开源项目源码托管(https://github. ...

  9. WPF--调用线程必须为 STA,因为许多 UI 组件都需要(转载)

    自VS2005开始,UI元素在不同线程中访问就受到限制了,当然你也可以解除这种限制 以下提供Framework3.0的解决方案发: public partial class Window1 : Win ...

  10. sprintf、strcpy和memcpy的区别

    做某题用到了sprintf把一个字符数组(字符串)写到二维字符数组里,然后耗时挺长的,想了想strcpy好像也可以,事实证明strcpy效率果然更高,然后想了想觉得memcpy好像也可以.实践了一下的 ...