Thomas.... You _can_ write in assembler, or disassemble the C# IL.
Here is some fun with bit level code that takes an int32 and outputs the
bit value by left shifting the
binary representation of the integer 32 times. This code demonstrates the
use of try catch IL and the
use of local variables to store temporary values. The CLR (Common Language
Runtime) will complain
if the try catch logic can lead to invalid states. We initialize the local
variable n_input before we try to
assign it a user value in try. This makes the CLR happy!
// TestILAssembler.il
// 11.28.04 Jeff Louie
.assembly extern mscorlib {}
.assembly TestILAssembler {.ver 1:0:1:0}
.method private static void Main(string[] args) cil managed
{
.entrypoint
.custom instance void [mscorlib]System.STAThreadAttribute::.ctor()
=
( 01 00 00 00 )
.maxstack 4
.locals init ([0] int32 n_counter,[1] int32 n_input)
.try // get user input
{
ldstr "Enter number: "
call void [mscorlib]System.Console::Write(string)
call string [mscorlib]System.Console::ReadLine()
call int32 [mscorlib]System.Int32:

arse(string)
// parse may throw exception
stloc.1 // place valid user input into n_input
leave.s got_value // leave don't branch from try
} // end .try
catch [mscorlib]System.Object
{
pop // remove exception from stack
ldstr "Invalid Number."
call void [mscorlib]System.Console::WriteLine(string)
leave exit // invalid input so exit program
} // end handler
got_value: ldloc.1 // push value n_input onto stack
dup
call void [mscorlib]System.Console::Write(int32)
ldstr " [Input value] "
call void
[mscorlib]System.Console::WriteLine(string)
// **** (for int i=0; i<32; i++) ****
load_counter: ldc.i4 0 // initialize n_counter 0
stloc.0 // store in local variable n_count
begin_loop: ldloc.0 // get current counter value
ldc.i4 32
bge end_loop // break loop if counter is >=32
dup
ldc.i4 0x80000000
// bit mask 10000000000000000000000000000000
and // clear all bits except most significant
ldc.i4 0x80000000
ceq // push 1 if most sig bit is true, else 0
call void [mscorlib]System.Console::Write(int32)
ldc.i4 1 // push 1
shl // *** shift left 1, zero least sig bit ****
ldloc.0 // get n_counter
ldc.i4 1
add // add 1 to n_counter, postfix increment
stloc.0 // store new n_counter value
br begin_loop // branch to loop again
// **** end for loop ****
end_loop: pop // remove input value should be all zeros
ldstr " [32 bit value] "
end_algo: call void
[mscorlib]System.Console::WriteLine(string)
exit: ldstr "JAL 11.25.04"
call void
[mscorlib]System.Console::WriteLine(string)
ret
} // end of method Main
Here is the output [input]:
Enter number: 10
10 [Input value]
00000000000000000000000000001010 [32 bit value]
JAL 11.28.04
Pretty cool!
Ahhh for the good old days of inline assembler. At least then you knew
exactly what was going on. .NET and managed code is wonderful in many
respects, but does present challenges in writing optimized loops.<
**********************************************************************
Sent via Fuzzy Software @
http://www.fuzzysoftware.com/
Comprehensive, categorised, searchable collection of links to ASP &
ASP.NET resources...