简介
要真正能够编程。NET,一个好的程序员会发现自己使用ILDASM中,MSIL反汇编程序,定期。这就需要在最低限度的能力,在阅读的MSIL的主管。不幸的是,最好的方式来学习阅读的MSIL是花一些时间来写它!因此,我思考的东西,我可以写,这将不会太大,但涵盖的概念,足以给我的能力,阅读的MSIL。
我记得有一个上大学的朋友,当他正在学习一门新的语言,将永远作为他的第一段代码生成曼德勃罗集(一个Mandelbrot集后记书面很有趣)。这似乎能够做的,所以我选择写在MSIL Mandelbrot集发电机。
代码使用Windows窗体显示一个新的窗口,然后绘制到这个图形表面像素。编译
编译的代码,只需通过ILASM / EXE mandelbrot.il。请记住,在您的路径ILASM - NET框架SDK的bin文件夹中的批处理文件corvars.bat会为您添加。
这应该产生在同一文件夹mandelbrot.exe。
{S0}该代码
代码继承System.Windows.Form和管理自己的画。
.class public auto ansi MandelBrotIL extends [System.Windows.Forms]System.Windows.Forms.Form {
这个类重写的OnPaint()System.Windows.Forms.Form中的方法(它继承)。 OnPaint中简单设置上绘制的图形,然后调用DrawMandelbrot()做实际的绘制:{C}
DrawMandelbrot()简单地实现的基本曼德尔布罗算法,其中的细节,可以发现在互联网上的许多地方。
.method private hidebysig instance
void DrawMandelbrot(class [System.Drawing]System.Drawing.Graphics g,
float32 fpMandelWidth, int32 ipIterations) cil managed {
.locals (
[0] float32 x, // Complex Real portion
[1] float32 y, // Complex Imaginary portion
[2] float32 fpGranularity, // Resolution of image on screen
[3] int32 ipPixelX, // X position on screen
[4] int32 ipPixelY, // Y position on screen
// Escape Velocity locals
[5] float32 fpX,
[6] float32 fpY,
[7] float32 fpXTemp,
[8] float32 fpYTemp,
[9] float32 fpX2, // X Squared
[10] float32 fpY2, // Y Squared
[11] int32 i // Loop variable used to calc escape velocity
)
// Calculate Granularity
ldc.r4 4
ldarg fpMandelWidth
div
stloc fpGranularity
// Initialise point on screen
ldc.i4.0
dup
stloc ipPixelX
stloc ipPixelY
// Start the real portion off
ldc.r4 -2.5
stloc x
NextReal:
// Start the imaginary portion off
ldc.r4 -1.5
stloc y
NextImaginary:
// Calculate Escape Velocity
// Initialise locals
ldloc x
stloc fpX
ldloc y
stloc fpY
ldloc x
dup
mul
stloc fpX2
ldloc y
dup
mul
stloc fpY2
// Initialise i
ldc.i4.0
stloc i
NextIteration:
ldloc x
ldloc fpX2
ldloc fpY2
sub
add
stloc fpXTemp
ldloc y
ldloc fpY
ldloc fpX
ldc.r4 2
mul
mul
add
stloc fpYTemp
// Calculate X squared
ldloc fpXTemp
dup
mul
stloc fpX2
// Calculate Y squared
ldloc fpYTemp
dup
mul
stloc fpY2
// If X Squared plus Y Squared is greater than 4, then we are guaranteed
// divergence to Infinity
ldloc fpX2
ldloc fpY2
add
ldc.r4 4
bge Divergence
// The previous values in the sequence become the current values in the sequence
ldloc fpXTemp
stloc fpX
ldloc fpYTemp
stloc fpY
// Incrememt i
ldc.i4.1
ldloc i
add
stloc i
ldloc i
ldarg ipIterations
blt NextIteration // Assume convergence to zero if we reach our iteration limit
Divergence:
// Draw Pixel. i is now the escape velocity
// Load the Graphics context
ldarg g
// Calculate the color based on the escape velocity
ldarg ipIterations
ldloc i
sub
stloc i
// Red
ldloc i
ldc.i4 12
mul
ldc.i4 256
rem
// Green
ldloc i
ldc.i4 16
mul
ldc.i4 256
rem
// Blue
ldloc i
ldc.i4 5
mul
ldc.i4 256
rem
call value class [System.Drawing]System.Drawing.Color
[System.Drawing]System.Drawing.Color::FromArgb(int32,
int32,
int32)
// Create a new Pen on the stack
ldc.r4 1
newobj instance void [System.Drawing]System.Drawing.Pen::.ctor(value class
[System.Drawing]System.Drawing.Color,
float32)
// Load the coords of the point to draw
ldloc ipPixelX
ldloc ipPixelY
// Width and Height
ldc.i4.2
dup
call instance void [System.Drawing]System.Drawing.Graphics::DrawRectangle(class
[System.Drawing]System.Drawing.Pen,
int32,
int32,
int32,
int32)
// Next PixelY
ldc.i4.1
ldloc ipPixelY
add
stloc ipPixelY
// Advance through the imaginary portion
ldloc y
ldloc fpGranularity
add
stloc y
ldloc y
ldc.r4 1.5
blt NextImaginary
// Advance through ipPixelX
ldc.i4.1
ldloc ipPixelX
add
stloc ipPixelX
// Start at the top of the screen for the next column
ldc.i4.0
stloc ipPixelY
// Advance through the real portion
ldloc x
ldloc fpGranularity
add
stloc x
ldloc x
ldc.r4 1.5
blt NextReal
ret
} // method