Jaa


Why are these nop instructions in my debug build?

If you run the sample code from the last post in release mode and debug mode you will notice that the msil for the test method are different. 

Method Program.TestMethod -- DEBUG
-------------------------------
0x0000 nop
0x0001 ldc.i4.0
0x0002 stloc.0
0x0003 ldloc.0
0x0004 ldc.i4.1
0x0005 add
0x0006 stloc.0
0x0007 ldloc.0
0x0008 ldc.i4 0x000008ff 2303
0x000d add
0x000e stloc.0
0x000f ldloc.0
0x0010 ldc.i4.2
0x0011 div
0x0012 stloc.1
0x0013 ldloc.1
0x0014 call 0x0a000019 Void WriteLine(Int32)
0x0019 nop
0x001a ldloc.0
0x001b call 0x0a000019 Void WriteLine(Int32)
0x0020 nop
0x0021 ldstr 0x700000df test
0x0026 call 0x0a000013 Void WriteLine(System.String)
0x002b nop
0x002c ret

Method Program.TestMethod -- RELEASE
-------------------------------
0x0000 ldc.i4.0
0x0001 stloc.0
0x0002 ldloc.0
0x0003 ldc.i4.1
0x0004 add
0x0005 stloc.0
0x0006 ldloc.0
0x0007 ldc.i4 0x000008ff 2303
0x000c add
0x000d stloc.0
0x000e ldloc.0
0x000f ldc.i4.2
0x0010 div
0x0011 stloc.1
0x0012 ldloc.1
0x0013 call 0x0a000019 Void WriteLine(Int32)
0x0018 ldloc.0
0x0019 call 0x0a000019 Void WriteLine(Int32)
0x001e ldstr 0x700000df test
0x0023 call 0x0a000013 Void WriteLine(System.String)
0x0028 ret

The debug code has all these nop instructions and the release mode does not.  What is the nop instruction?  Nop mean no operation.  Why would these nop instructions exist in debug mode and not in release?  After some searching on the internet it looks like the nop command is used in debug mode for break points.  Try this in visual studio.  Change your solution to debug mode and put a break point on a bracket. In code below I put the breakpoint on the top bracket after the word get.  Run the solution in debug mode then change the solution to release mode and run.  Notice how in debug mode you able to break on the actual bracket but in release mode you can only break on the line with actual code.

 

            public int Value
            { // Breakpoint here
                get
                {
                    return _value;
                }
            }

 

        private static void TestMethod()
        { // Break Point here
           
        }

 

Check out the links below for more info. 

Debugging and nop Instructions

Visual Basic .NET allows you to set breakpoints on non-executing lines of code such as End If, End Sub, and Dim statements. To facilitate this popular debugging technique, the compiler inserts nop instructions as placeholders for the non-executing lines of code (since non-executing lines are not translated into IL instructions). The nop instruction is a "no operation" instruction—it does not perform any meaningful work yet can consume a processing cycle.

https://msdn.microsoft.com/en-us/library/aa289509.aspx  -- Scroll down to Debugging and nop Instruction section

https://msdn.microsoft.com/en-us/library/system.reflection.emit.opcodes.nop.aspx

Share/Save/Bookmark

Comments

  • Anonymous
    June 15, 2010
    I was wondering what those were for. Sounds like there is a lot less magic going on than I had suspected. Thanks for the easy to follow explanation!