Click here to Skip to main content
6,595,444 members and growing! (15,083 online)
Email Password   helpLost your password?
Languages » MSIL » General     Intermediate License: The BSD License

Mandelbrot set in MSIL

By Richard Birkby

Demonstrates the use of Windows Forms, GDI+ from CIL
MSIL, Windows, .NET 1.0, Dev
Posted:3 Oct 2001
Updated:23 Jun 2002
Views:104,260
Bookmarked:26 times
Announcements
Loading...
 
Search    
Advanced Search
Add to IE Search
printPrint   add Share
      Discuss Discuss   Broken Article?Report  
16 votes for this article.
Popularity: 5.19 Rating: 4.31 out of 5

1

2

3
2 votes, 50.0%
4
2 votes, 50.0%
5

Introduction

To really be able to program .Net, a good programmer will find themselves using ILDASM, the MSIL disassembler, on a regular basis. This necessitates an ability to, at a minimum, be competent at reading MSIL. Unfortunately, the best way to learn to read MSIL is to spend some time writing it! Thus, I set about thinking of something I could write, which would not be too large, but would cover enough of the concepts to give me an ability to read MSIL.

I remember a friend at college who, when he was learning a new language, would always generate Mandelbrot sets as his first piece of code (a mandelbrot set written in Postscript was amusing). This seemed do-able, so I chose to write a Mandelbrot set generator in MSIL.

The code uses Windows Forms to show a new window, then draws the pixels onto this graphics surface.

Compiling

Compile the code simply by ilasm /exe mandelbrot.il. Remember to have ilasm in your path - the batch file corvars.bat in the bin folder of the .Net Framework SDK will add it for you.

This should generate mandelbrot.exe in the same folder.

Screenshot of Mandelbrot.il

The code

The code inherits from System.Windows.Form and manages its own painting.

.class public auto ansi MandelBrotIL extends [System.Windows.Forms]System.Windows.Forms.Form {

This class overrides the OnPaint() method of System.Windows.Forms.Form (which it inherits from). OnPaint simply sets up the graphics to draw onto, and then calls DrawMandelbrot() to do the actual drawing:

.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
}

DrawMandelbrot() simply implements a basic Mandelbrot algorithm, details of which can be found in many places on the Internet.

.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

License

This article, along with any associated source code and files, is licensed under The BSD License

About the Author

Richard Birkby


Member
Richard Birkby is a software engineer from London, UK, specializing in .Net. Richard has coded for many different sized companies from small venture-capital funded start-ups, to multi-national corporations (ie Microsoft). When he's not programming, he enjoys driving his sports car or eating curry (although never at the same time!).

Richard helps run CurryPages.com and has several other covert ventures in development. Stay tuned!
Occupation: Web Developer
Location: United Kingdom United Kingdom

Other popular MSIL articles:

Article Top
You must Sign In to use this message board.
FAQ FAQ 
 
Noise Tolerance  Layout  Per page   
 Msgs 1 to 15 of 15 (Total in Forum: 15) (Refresh)FirstPrevNext
QuestionDid you... PinmemberDrew Noakes4:49 20 Mar '08  
GeneralMSIL to HEX PinmemberTanoFaye6:11 8 Mar '04  
AnswerRe: MSIL to HEX PinmemberBehind The Scene14:36 21 Jan '07  
GeneralThis is very nice. PinmemberMarc Clifton11:09 26 Dec '02  
GeneralHelp!, I need to know how to use msil PinsussSungkyou Che19:59 1 Aug '02  
GeneralRe: Help!, I need to know how to use msil PinmemberBarrett80812:36 12 Aug '02  
GeneralIt don't run Pinmembersultan_of_6string1:33 21 Jun '02  
GeneralRe: It don't run PinmemberRichard Birkby8:03 21 Jun '02  
GeneralRe: You suck PinmemberRichard Birkby4:06 30 May '02  
GeneralPenis envy from a VB programmer? PinmemberMike Asher11:47 24 Jun '02  
Generalinteresting... PinmemberPer-Olov Jernberg7:33 19 Dec '01  
GeneralRe: interesting... PinmemberChris Losinger7:40 19 Dec '01  
GeneralRe: interesting... PinmemberAnonymous21:15 18 Jun '02  
GeneralRe: interesting... PinmemberJoel Matthias6:11 24 Jun '02  
GeneralRe: interesting... PinmemberChristian Graus14:00 24 Jun '02  

General General    News News    Question Question    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

PermaLink | Privacy | Terms of Use
Last Updated: 23 Jun 2002
Editor: Chris Maunder
Copyright 2001 by Richard Birkby
Everything else Copyright © CodeProject, 1999-2009
Web10 | Advertise on the Code Project