在MSIL简介系列的第2部分,我将会探索局部变量的使用。如果没有变量,那么一个程序将会很无聊。为了解释如何使用变量,让我们写一个简单的求和程序。

在一个MSIL函数中,变量可以通过.locals指令声明.

.locals init (int32 first, int32 second, int32 result)

这个代码为当前函数声明了3个局部变量。本例中,它们恰好是 int32类型, 是System.Int32类型的别名。 init表示每个变量都需要被初始化成默认值。也可以忽略变量名,那样的话你需要通过从0开始的下标来引用它们。当然,使用变量名可以提高可读性。

在继续讲解之前,我希望确定你了解MSIL如何使用栈。当你想要给一个指令传值时,这些值需要被放到栈中。为了读取这些值,指令从栈中把它们拿出来。相似的,当调用一个函数时,你需要把引用依次推入栈中。然后函数会从栈中取出引用。为了把一个值推入栈中,用ldloc指令指示拥有那个值的变量。为了从栈中弹出一个值,使用stloc指令指示你要在哪个变量中存储这个值。记住,值是直接存储在栈中的,但是对象不是。对象的引用被存储在栈中,但对象在堆中被分配。

下一步是从用户那里获取数字。

ldstr "First number: "
call void [mscorlib]System.Console::Write(string)
call string [mscorlib]System.Console::ReadLine()
call int32 [mscorlib]System.Int32::Parse(string)
stloc first

就像是我在Part 1中提到的,ldstr指令把字符串推入栈中并调用Write函数,Write函数把变量从栈中弹出。下一个call指令调用返回string的ReadLine函数。返回的string被推入栈中,由于string已经在栈中,我们简单地调用 Int32::parse 函数把字符串弹出并推入等值的int32。注意,我为了讲解更清楚,忽略了错误处理。stloc指令会弹出栈中的值并把它存储在first局部变量中。从用户获取第二个数字的方法和这个相同,只是第二个数字的值需要被存储在 ‘second’ 局部变量中。

既然我们已经从标准输入中获取了两个值,是时候把它们相加。add指令可以达到我们的目的。

ldloc first
ldloc second
add
stloc result

add指令从栈中弹出两个值并计算它们的和。为了把局部变量的值推入栈中,我们使用了ldloc指令(load local),当add指令完成的时候,它会把结果推入栈中。接着程序使用stloc指令(set local)从栈中弹出值,并将其存储在名为 ‘result’ 的局部变量中。

最后一步是向用户展示结果。

ldstr "{0} + {1} = {2}"ldloc first
box int32ldloc second
box int32ldloc result
box int32call void [mscorlib]System.Console::WriteLine(string, object, object, object)

我们使用WriteLine重载函数。WriteLine函数的每个参数,都必须依次被推入栈中。因为数字是作为 int32值类型被存储的,我们需要为每个值装箱;否则和函数签名不匹配。

ldloc指令把每个变量推入栈中。然后为每个int32参数使用box指令。装箱会从栈中弹出值,构造一个包含值的副本的对象,然后把引用推入栈中。

下面是一个完整的程序。

.method static void main()
{.entrypoint.maxstack 4.locals init (int32 first,int32 second,int32 result)ldstr "First number: "call void [mscorlib]System.Console::Write(string)call string [mscorlib]System.Console::ReadLine()call int32 [mscorlib]System.Int32::Parse(string)stloc firstldstr "Second number: "call void [mscorlib]System.Console::Write(string)call string [mscorlib]System.Console::ReadLine()call int32 [mscorlib]System.Int32::Parse(string)stloc secondldloc firstldloc secondaddstloc resultldstr "{0} + {1} = {2}"ldloc firstbox int32ldloc secondbox int32ldloc resultbox int32call void [mscorlib]System.Console::WriteLine(string, object, object, object)   ret
}

这里例子还有需要注意的一点是,我指示了main函数最多使用4个栈槽。这是为了和WriteLine函数的4个参数相匹配。

MSIL简介 - Part 2 - 使用局部变量相关推荐

  1. MSIL简介 - Part 3 - 定义类型

    在本期的MSIL 系列中,我将描述类型是怎么定义的. 下面是一个最小引用类型,House. .class Kerr.RealEstate.House {.method public void .cto ...

  2. MSIL简介 - Part1 - HelloWorld

    原文链接 让我们从一个简单的main函数开始.和C#不同,CLI不要求一个方法属于一个类.入口函数也不一定要叫做main:但是为了简单起见,我将会使用这个命名. .method static void ...

  3. C语言 全局变量和局部变量区别 - C语言零基础入门教程

    目录 一.全局变量和局部变量简介 1.全局变量简介 2.局部变量简介 二.全局变量和局部变量注意事项 三.猜你喜欢 零基础 C/C++ 学习路线推荐 : C/C++ 学习目录 >> C 语 ...

  4. C++静态成员变量和成员函数

    静态成员变量和成员函数 简介 sizeof不将静态成员变量的大小计算在内 可以通过类名来访问静态成员 静态成员函数不能访问类的非静态成员 简介 static加在局部变量的前面改变其存储类型使之成为静态 ...

  5. ThreadLocal之强、弱、软、虚引用

    1.ThreadLocal简介 ThreadLocal提供线程局部变量.这些变量与正常的变量不同,因为每一个线程在访问ThreadLocal实例的时候(通过其get或set方法)都有自己的.独立初始化 ...

  6. MSIL(0):简介

    Microsoft Intermediate Language (MSIL)微软中间语言 MSIL是将.NET代码转化为机器语言的一个中间过程.它是一种介于高级语言和基于Intel的汇编语言的伪汇编语 ...

  7. C#程序设计语言Version2.0简介

    [翻译] lover_P 2004-01-26 ---------------------------------------------------------------------------- ...

  8. LESS CSS 框架简介与使用

    简介 CSS(层叠样式表)是一门历史悠久的标记性语言,同 HTML 一道,被广泛应用于万维网(World Wide Web)中.HTML 主要负责文档结构的定义,CSS 负责文档表现形式或样式的定义. ...

  9. 线程编程常见API简介(中)

    2019独角兽企业重金招聘Python工程师标准>>> 一.概述 在<线程编程常见API简介(上) >中讲述了有关线程创建过程中常用的 API 的使用方法,本节继续讲述有 ...

最新文章

  1. PostgreSQL-数据复制
  2. 你能排第几?2016互联网行业薪酬数据分析
  3. JS使用onscroll、scrollTop实现图片懒加载
  4. mysql iops_MySQL实例IOPS使用率高的原因和解决方法
  5. ap统计学需要什么计算机,准备AP统计学考试不需要死背公式
  6. 查看Mysql数据库有多大
  7. 【DB2学习文档之七】SQL for DB2
  8. 后台模板 开源_3个开源样板网页设计模板
  9. 原始图片中的ROI如何映射到到feature map?(转)
  10. 51Nod-1010 只包含因子2 3 5的数【打表+排序+二分搜索】
  11. W Zong / A Robust Open-source Algorithm to Detect Onset and Duration of QRS Complexes
  12. Harmony OS — RadioButton RadioContainer单选按钮单选按钮组
  13. 基于MyEclipse+Mysql+Tomcat+SSH开发的运动会管理系统
  14. Android实现访斗鱼视频播放
  15. 在Centos操作系统下安装mysql8.0
  16. 计算机知识竞赛的策划案,计算机趣味知识竞赛活动策划书
  17. 给tftp服务器传文件,袖针文件传输服务器Tftpd32
  18. Android大话设计模式 第一章----针对接口编程---问世间情为何物 直教人生死相许
  19. 基于PaddleX的岩石识别
  20. python学后总结_学员 | 斥巨资学完数据分析后,给大家总结了7个小建议

热门文章

  1. java inverse_映射中的inverse
  2. 100天精通Python(数据分析篇)——第72天:Pandas文本数据处理方法之判断类型、去除空白字符、拆分和连接
  3. 西南交大计算机考研三本,西南交大考研经验:从三本到211.doc
  4. Android自定义圆角圆形图片
  5. Cat1模组蓄“光”发展,广和通全场景助力光伏行业零碳发电
  6. 存储过程oracle面试,oracle-plsq存储过程l面试题
  7. 网站建设,网站运营技巧和优化方案
  8. qq五笔提示说内部错误无法登录
  9. 想要在PDF文档中提取签名和图像信息?有这篇Aspose.PDF for .NET干货教程就够了!
  10. iOS小课堂: 集成 《阿里百川》教程( 打开商品详情页、 淘宝账号授权登录、 完成交易闭环)