MSIL编程:绘制曼德勃罗集

在.NET框架中,MSIL(Microsoft Intermediate Language)是一种中间语言,用于在.NET环境下编译和执行代码。如果经常使用ILDASM(MSIL反编译器),那么至少需要能够阅读MSIL。不幸的是,学习阅读MSIL的最佳方式是花费一些时间来编写它。因此,想到了一个既不太复杂,又能涵盖足够概念的项目,以便能够阅读MSIL。

记得在大学时,一个朋友在学习新语言时,总是首先生成曼德勃罗集作为他的第一段代码(用Postscript编写的曼德勃罗集很有趣)。这似乎可行,所以选择用MSIL编写一个曼德勃罗集生成器。

代码使用Windows Forms来显示一个新窗口,然后在该图形表面上绘制像素。

编译

通过以下命令编译代码:

ilasm /exe mandelbrot.il

请确保将ilasm添加到路径中 -.NETFramework SDK的bin文件夹中的批处理文件corvars.bat会为添加它。

这应该会在同一个文件夹中生成mandelbrot.exe。

代码解析

代码继承自System.Windows.Forms.Form,并管理自己的绘制。

MSIL代码如下:

.class public auto ansi MandelBrotIL extends [System.Windows.Forms]System.Windows.Forms.Form { .method family hidebysig virtual instance void OnPaint(class [System.Windows.Forms]System.Windows.Forms.PaintEventArgs e) cil managed { ldarg.0 ldarg e call instance class [System.Drawing]System.Drawing.Graphics [System.Windows.Forms]System.Windows.Forms.PaintEventArgs::get_Graphics() ldc.r4 200 // Width in pixels ldc.i4 250 // Iterations before we assume convergence to zero call instance void ThunderMain.Demo.MandelBrotIL::DrawMandelbrot(class [System.Drawing]System.Drawing.Graphics, float32, int32) ret } .method private hidebysig instance void DrawMandelbrot(class [System.Drawing]System.Drawing.Graphics g, float32 fpMandelWidth, int32 ipIterations) cil managed { // Locals declaration... // Calculate Granularity ldc.r4 4 ldarg fpMandelWidth div stloc fpGranularity // Initialize point on screen ldc.i4.0 dup stloc ipPixelX stloc ipPixelY // Start the real portion off ldc.r4 -2.5 stloc x // Start the imaginary portion off ldc.r4 -1.5 stloc y // Calculate Escape Velocity... // Draw Pixel... // Next PixelY... // Advance through the imaginary portion... // Advance through ipPixelX... // Start at the top of the screen for the next column... // Advance through the real portion... ret } }

DrawMandelbrot()方法简单地实现了一个基本的曼德勃罗算法,其详细信息可以在互联网上的许多地方找到。

在这个方法中,定义了一组局部变量来存储计算过程中的值。计算了屏幕上图像的分辨率(Granularity),初始化了屏幕上的点(ipPixelX, ipPixelY),并开始了实部(x)和虚部(y)的计算。

接下来,进入一个循环,计算逃逸速度。如果X平方加上Y平方大于4,那么可以确定它将发散到无穷大。否则,继续迭代,直到达到迭代限制,然后假设它收敛到零。

在每次迭代中,更新X和Y的值,并计算X平方和Y平方。如果它们之和大于4,绘制像素,并根据逃逸速度计算颜色。然后,继续绘制下一个像素。

沪ICP备2024098111号-1
上海秋旦网络科技中心:上海市奉贤区金大公路8218号1幢 联系电话:17898875485