/// <summary> /// Initializes a new instance of the <see cref="TypeInitializerSchedulerStage"/> class. /// </summary> public TypeInitializerSchedulerStage() { basicBlocks = new BasicBlocks(); var block = basicBlocks.CreateBlock(BasicBlock.PrologueLabel); basicBlocks.AddHeaderBlock(block); context = new Context(block); }
/// <summary> /// Creates the ISR methods. /// </summary> private void CreateExceptionVector() { var type = TypeSystem.GetTypeByName("Mosa.Kernel.x86", "IDT"); if (type == null) return; var method = type.FindMethodByName("ExceptionHandlerType"); if (method == null) return; Operand exceptionMethod = Operand.CreateSymbolFromMethod(TypeSystem, method); Operand esp = Operand.CreateCPURegister(TypeSystem.BuiltIn.I4, GeneralPurposeRegister.ESP); BasicBlocks basicBlocks = new BasicBlocks(); InstructionSet instructionSet = new InstructionSet(25); Context ctx = instructionSet.CreateNewBlock(basicBlocks); basicBlocks.AddHeaderBlock(ctx.BasicBlock); // TODO - setup stack for call to the managed exception handler //1. //2. //3. Call the managed exception handler ctx.AppendInstruction(X86.Call, null, exceptionMethod); var vectorMethod = Compiler.CreateLinkerMethod("ExceptionVector"); Compiler.CompileMethod(vectorMethod, basicBlocks, instructionSet); }
/// <summary> /// Initializes a new instance of the <see cref="TypeInitializerSchedulerStage"/> class. /// </summary> public TypeInitializerSchedulerStage() { basicBlocks = new BasicBlocks(); instructionSet = new InstructionSet(25); context = instructionSet.CreateNewBlock(basicBlocks); basicBlocks.AddHeaderBlock(context.BasicBlock); context.AppendInstruction(IRInstruction.Prologue); }
protected override void Run() { if (multibootMethod == null) { multibootHeader = Linker.CreateSymbol(MultibootHeaderSymbolName, SectionKind.Text, 1, 0x30); multibootMethod = Compiler.CreateLinkerMethod("MultibootInit"); Linker.EntryPoint = Linker.GetSymbol(multibootMethod.FullName, SectionKind.Text); WriteMultibootHeader(); Linker.CreateSymbol(MultibootEAX, SectionKind.BSS, Architecture.NativeAlignment, Architecture.NativePointerSize); Linker.CreateSymbol(MultibootEBX, SectionKind.BSS, Architecture.NativeAlignment, Architecture.NativePointerSize); return; } var typeInitializerSchedulerStage = Compiler.PostCompilePipeline.FindFirst <TypeInitializerSchedulerStage>(); var ecx = Operand.CreateCPURegister(TypeSystem.BuiltIn.I4, GeneralPurposeRegister.ECX); var eax = Operand.CreateCPURegister(TypeSystem.BuiltIn.I4, GeneralPurposeRegister.EAX); var ebx = Operand.CreateCPURegister(TypeSystem.BuiltIn.I4, GeneralPurposeRegister.EBX); var ebp = Operand.CreateCPURegister(TypeSystem.BuiltIn.I4, GeneralPurposeRegister.EBP); var multibootEax = Operand.CreateUnmanagedSymbolPointer(TypeSystem, MultibootEAX); var multibootEbx = Operand.CreateUnmanagedSymbolPointer(TypeSystem, MultibootEBX); var basicBlocks = new BasicBlocks(); var block = basicBlocks.CreateBlock(); basicBlocks.AddHeaderBlock(block); var ctx = new Context(block); // set sentinel on the stack to indicate the start of the stack var zero = Operand.CreateConstant(TypeSystem.BuiltIn.I4, 0); ctx.AppendInstruction(X86.Mov, Operand.CreateMemoryAddress(TypeSystem.BuiltIn.I4, ebp, 0), zero); ctx.AppendInstruction(X86.Mov, ecx, multibootEax); ctx.AppendInstruction(X86.Mov, Operand.CreateMemoryAddress(TypeSystem.BuiltIn.I4, ecx, 0), eax); ctx.AppendInstruction(X86.Mov, ecx, multibootEbx); ctx.AppendInstruction(X86.Mov, Operand.CreateMemoryAddress(TypeSystem.BuiltIn.I4, ecx, 0), ebx); // call type initializer var entryPoint = Operand.CreateSymbolFromMethod(TypeSystem, typeInitializerSchedulerStage.TypeInitializerMethod); ctx.AppendInstruction(X86.Call, null, entryPoint); // should never get here ctx.AppendInstruction(X86.Ret); Compiler.CompileMethod(multibootMethod, basicBlocks, 0); }
private static void CreatePrologueAndEpilogueBlocks(InstructionSet instructionSet, BasicBlocks basicBlocks) { // Create the prologue block var context = instructionSet.CreateNewBlock(basicBlocks, BasicBlock.PrologueLabel); // Add a jump instruction to the first block from the prologue context.AppendInstruction(IRInstruction.Jmp); context.SetBranch(0); var prologue = context.BasicBlock; basicBlocks.AddHeaderBlock(prologue); // Create the epilogue block context = instructionSet.CreateNewBlock(basicBlocks, BasicBlock.EpilogueLabel); var epilogue = context.BasicBlock; }
/// <summary> /// Creates the interrupt service routine (ISR) methods. /// </summary> private void CreateInterruptVectors() { var type = TypeSystem.GetTypeByName("Mosa.Kernel.x86", "IDT"); if (type == null) { return; } var method = type.FindMethodByName("ProcessInterrupt"); if (method == null) { return; } Operand interrupt = Operand.CreateSymbolFromMethod(TypeSystem, method); Operand esp = Operand.CreateCPURegister(TypeSystem.BuiltIn.I4, GeneralPurposeRegister.ESP); for (int i = 0; i <= 255; i++) { var basicBlocks = new BasicBlocks(); var block = basicBlocks.CreateBlock(); basicBlocks.AddHeaderBlock(block); var ctx = new Context(block); ctx.AppendInstruction(X86.Cli); if (i <= 7 || i >= 16 | i == 9) // For IRQ 8, 10, 11, 12, 13, 14 the cpu will automatically pushed the error code { ctx.AppendInstruction(X86.Push, null, Operand.CreateConstant(TypeSystem, 0)); } ctx.AppendInstruction(X86.Push, null, Operand.CreateConstant(TypeSystem, i)); ctx.AppendInstruction(X86.Pushad); ctx.AppendInstruction(X86.Push, null, esp); ctx.AppendInstruction(X86.Call, null, interrupt); ctx.AppendInstruction(X86.Pop, esp); ctx.AppendInstruction(X86.Popad); ctx.AppendInstruction(X86.Add, esp, esp, Operand.CreateConstant(TypeSystem, 8)); ctx.AppendInstruction(X86.Sti); ctx.AppendInstruction(X86.IRetd); var interruptMethod = Compiler.CreateLinkerMethod("InterruptISR" + i.ToString()); Compiler.CompileMethod(interruptMethod, basicBlocks, 0); } }
protected override void Run() { Debug.Assert(setupMethod == null, "SSE setup method already generated!"); setupMethod = Compiler.CreateLinkerMethod("SSEInit"); var eax = Operand.CreateCPURegister(TypeSystem.BuiltIn.U4, GeneralPurposeRegister.EAX); var cr0 = Operand.CreateCPURegister(TypeSystem.BuiltIn.U4, ControlRegister.CR0); var cr4 = Operand.CreateCPURegister(TypeSystem.BuiltIn.U4, ControlRegister.CR4); var basicBlocks = new BasicBlocks(); var block = basicBlocks.CreateBlock(); basicBlocks.AddHeaderBlock(block); var ctx = new Context(block); /* * ;enable SSE and the like * mov eax, cr0 * and ax, 0xFFFB ;clear coprocessor emulation CR0.EM * or ax, 0x2 ;set coprocessor monitoring CR0.MP * mov cr0, eax * mov eax, cr4 * or ax, 3 << 9 ;set CR4.OSFXSR and CR4.OSXMMEXCPT at the same time * mov cr4, eax * ret */ ctx.AppendInstruction(X86.MovCR, eax, cr0); ctx.AppendInstruction(X86.And, eax, eax, Operand.CreateConstant(TypeSystem.BuiltIn.U4, 0xFFFB)); ctx.AppendInstruction(X86.Or, eax, eax, Operand.CreateConstant(TypeSystem.BuiltIn.U4, 0x2)); ctx.AppendInstruction(X86.MovCR, cr0, eax); ctx.AppendInstruction(X86.MovCR, eax, cr4); ctx.AppendInstruction(X86.Or, eax, eax, Operand.CreateConstant(TypeSystem.BuiltIn.U4, 0x600)); ctx.AppendInstruction(X86.MovCR, cr4, eax); ctx.AppendInstruction(X86.Ret); Compiler.CompileMethod(setupMethod, basicBlocks, 0); var typeInitializerSchedulerStage = Compiler.PostCompilePipeline.FindFirst <TypeInitializerSchedulerStage>(); typeInitializerSchedulerStage.Schedule(setupMethod); }
private static BasicBlocks CreateBasicBlockInstructionSet() { var basicBlocks = new BasicBlocks(); var block = basicBlocks.CreateBlock(); basicBlocks.AddHeaderBlock(block); var context = new Context(block); context.AppendInstruction(IRInstruction.Nop); context.AppendInstruction(IRInstruction.Nop); context.AppendInstruction(IRInstruction.Nop); context.AppendInstruction(IRInstruction.Nop); context.AppendInstruction(IRInstruction.Nop); context.AppendInstruction(IRInstruction.Nop); return basicBlocks; }
private static BasicBlocks CreateBasicBlockInstructionSet() { var basicBlocks = new BasicBlocks(); var block = basicBlocks.CreateBlock(); basicBlocks.AddHeaderBlock(block); var context = new Context(block); context.AppendInstruction(IRInstruction.Nop); context.AppendInstruction(IRInstruction.Nop); context.AppendInstruction(IRInstruction.Nop); context.AppendInstruction(IRInstruction.Nop); context.AppendInstruction(IRInstruction.Nop); context.AppendInstruction(IRInstruction.Nop); return(basicBlocks); }
protected override void Run() { var typeInitializer = Compiler.PostCompilePipeline.FindFirst<TypeInitializerSchedulerStage>().TypeInitializerMethod; var basicBlocks = new BasicBlocks(); var block = basicBlocks.CreateBlock(); basicBlocks.AddHeaderBlock(block); var context = new Context(block); var entryPoint = Operand.CreateSymbolFromMethod(TypeSystem, typeInitializer); context.AppendInstruction(IRInstruction.Call, null, entryPoint); context.InvokeMethod = typeInitializer; var method = Compiler.CreateLinkerMethod(StartUpName); Compiler.CompileMethod(method, basicBlocks, 0); Linker.EntryPoint = Linker.GetSymbol(method.FullName, SectionKind.Text); }
protected override void Run() { Debug.Assert(setupMethod == null, "SSE setup method already generated!"); setupMethod = Compiler.CreateLinkerMethod("SSEInit"); var eax = Operand.CreateCPURegister(TypeSystem.BuiltIn.U4, GeneralPurposeRegister.EAX); var cr0 = Operand.CreateCPURegister(TypeSystem.BuiltIn.U4, ControlRegister.CR0); var cr4 = Operand.CreateCPURegister(TypeSystem.BuiltIn.U4, ControlRegister.CR4); var basicBlocks = new BasicBlocks(); var block = basicBlocks.CreateBlock(); basicBlocks.AddHeaderBlock(block); var ctx = new Context(block); /* ;enable SSE and the like mov eax, cr0 and ax, 0xFFFB ;clear coprocessor emulation CR0.EM or ax, 0x2 ;set coprocessor monitoring CR0.MP mov cr0, eax mov eax, cr4 or ax, 3 << 9 ;set CR4.OSFXSR and CR4.OSXMMEXCPT at the same time mov cr4, eax ret */ ctx.AppendInstruction(X86.MovCR, eax, cr0); ctx.AppendInstruction(X86.And, eax, eax, Operand.CreateConstant(TypeSystem.BuiltIn.U4, 0xFFFB)); ctx.AppendInstruction(X86.Or, eax, eax, Operand.CreateConstant(TypeSystem.BuiltIn.U4, 0x2)); ctx.AppendInstruction(X86.MovCR, cr0, eax); ctx.AppendInstruction(X86.MovCR, eax, cr4); ctx.AppendInstruction(X86.Or, eax, eax, Operand.CreateConstant(TypeSystem.BuiltIn.U4, 0x600)); ctx.AppendInstruction(X86.MovCR, cr4, eax); ctx.AppendInstruction(X86.Ret); Compiler.CompileMethod(setupMethod, basicBlocks, 0); var typeInitializerSchedulerStage = Compiler.PostCompilePipeline.FindFirst<TypeInitializerSchedulerStage>(); typeInitializerSchedulerStage.Schedule(setupMethod); }
protected override void Run() { TypeInitializerSchedulerStage typeInitializerSchedulerStage = Compiler.Pipeline.FindFirst<TypeInitializerSchedulerStage>(); BasicBlocks basicBlocks = new BasicBlocks(); InstructionSet instructionSet = new InstructionSet(25); Context context = instructionSet.CreateNewBlock(basicBlocks); basicBlocks.AddHeaderBlock(context.BasicBlock); Operand entryPoint = Operand.CreateSymbolFromMethod(TypeSystem, typeInitializerSchedulerStage.TypeInitializerMethod); context.AppendInstruction(IRInstruction.Call, null, entryPoint); context.MosaMethod = typeInitializerSchedulerStage.TypeInitializerMethod; //context.AppendInstruction(IRInstruction.Break); MosaMethod method = Compiler.CreateLinkerMethod(StartUpName); Compiler.CompileMethod(method, basicBlocks, instructionSet); Linker.EntryPoint = Linker.GetSymbol(method.FullName); }
protected override void Run() { var typeInitializer = Compiler.PostCompilePipeline.FindFirst <TypeInitializerSchedulerStage>().TypeInitializerMethod; var basicBlocks = new BasicBlocks(); var block = basicBlocks.CreateBlock(); basicBlocks.AddHeaderBlock(block); var context = new Context(block); var entryPoint = Operand.CreateSymbolFromMethod(TypeSystem, typeInitializer); context.AppendInstruction(IRInstruction.Call, null, entryPoint); context.InvokeMethod = typeInitializer; var method = Compiler.CreateLinkerMethod(StartUpName); Compiler.CompileMethod(method, basicBlocks, 0); Linker.EntryPoint = Linker.GetSymbol(method.FullName, SectionKind.Text); }
/// <summary> /// Creates the interrupt service routine (ISR) methods. /// </summary> private void CreateInterruptVectors() { var type = TypeSystem.GetTypeByName("Mosa.Kernel.x86", "IDT"); if (type == null) return; var method = type.FindMethodByName("ProcessInterrupt"); if (method == null) return; Operand interrupt = Operand.CreateSymbolFromMethod(TypeSystem, method); Operand esp = Operand.CreateCPURegister(TypeSystem.BuiltIn.I4, GeneralPurposeRegister.ESP); for (int i = 0; i <= 255; i++) { var basicBlocks = new BasicBlocks(); var block = basicBlocks.CreateBlock(); basicBlocks.AddHeaderBlock(block); var ctx = new Context(block); ctx.AppendInstruction(X86.Cli); if (i <= 7 || i >= 16 | i == 9) // For IRQ 8, 10, 11, 12, 13, 14 the cpu will automatically pushed the error code ctx.AppendInstruction(X86.Push, null, Operand.CreateConstant(TypeSystem, 0)); ctx.AppendInstruction(X86.Push, null, Operand.CreateConstant(TypeSystem, i)); ctx.AppendInstruction(X86.Pushad); ctx.AppendInstruction(X86.Push, null, esp); ctx.AppendInstruction(X86.Call, null, interrupt); ctx.AppendInstruction(X86.Pop, esp); ctx.AppendInstruction(X86.Popad); ctx.AppendInstruction(X86.Add, esp, esp, Operand.CreateConstant(TypeSystem, 8)); ctx.AppendInstruction(X86.Sti); ctx.AppendInstruction(X86.IRetd); var interruptMethod = Compiler.CreateLinkerMethod("InterruptISR" + i.ToString()); Compiler.CompileMethod(interruptMethod, basicBlocks, 0); } }
private void DecodeProtectedRegionTargets() { foreach (var handler in MethodCompiler.Method.ExceptionHandlers) { if (handler.TryStart != 0) { var block = GetBlockByLabel(handler.TryStart); } if (handler.TryEnd != 0) { var block = GetBlockByLabel(handler.TryEnd); } if (handler.HandlerStart != 0) { var block = GetBlockByLabel(handler.HandlerStart); BasicBlocks.AddHeaderBlock(block); } if (handler.FilterOffset != null) { var block = GetBlockByLabel(handler.FilterOffset.Value); BasicBlocks.AddHeaderBlock(block); } } }
private static void CreatePrologueAndEpilogueBlocks(InstructionSet instructionSet, BasicBlocks basicBlocks) { // Create the prologue block Context context = new Context(instructionSet); // Add a jump instruction to the first block from the prologue context.AppendInstruction(IRInstruction.Jmp); context.SetBranch(0); context.Label = BasicBlock.PrologueLabel; var prologue = basicBlocks.CreateBlock(BasicBlock.PrologueLabel, context.Index); basicBlocks.AddHeaderBlock(prologue); // Create the epilogue block context = new Context(instructionSet); // Add null instruction, necessary to generate a block index context.AppendInstruction(null); context.Label = BasicBlock.EpilogueLabel; var epilogue = basicBlocks.CreateBlock(BasicBlock.EpilogueLabel, context.Index); }
protected override void Run() { if (multibootMethod == null) { multibootMethod = Compiler.CreateLinkerMethod("MultibootInit"); WriteMultibootHeader(); return; } var typeInitializerSchedulerStage = Compiler.Pipeline.FindFirst<TypeInitializerSchedulerStage>(); var ecx = Operand.CreateCPURegister(TypeSystem.BuiltIn.I4, GeneralPurposeRegister.ECX); var eax = Operand.CreateCPURegister(TypeSystem.BuiltIn.I4, GeneralPurposeRegister.EAX); var ebx = Operand.CreateCPURegister(TypeSystem.BuiltIn.I4, GeneralPurposeRegister.EBX); var basicBlocks = new BasicBlocks(); var instructionSet = new InstructionSet(25); var ctx = instructionSet.CreateNewBlock(basicBlocks); basicBlocks.AddHeaderBlock(ctx.BasicBlock); ctx.AppendInstruction(X86.Mov, ecx, Operand.CreateConstantSignedInt(TypeSystem, 0x200000)); ctx.AppendInstruction(X86.Mov, Operand.CreateMemoryAddress(TypeSystem.BuiltIn.I4, ecx, 0), eax); ctx.AppendInstruction(X86.Mov, Operand.CreateMemoryAddress(TypeSystem.BuiltIn.I4, ecx, 4), ebx); var entryPoint = Operand.CreateSymbolFromMethod(TypeSystem, typeInitializerSchedulerStage.TypeInitializerMethod); ctx.AppendInstruction(X86.Call, null, entryPoint); ctx.AppendInstruction(X86.Ret); Compiler.CompileMethod(multibootMethod, basicBlocks, instructionSet); Linker.EntryPoint = Linker.GetSymbol(multibootMethod.FullName); }
protected override void Run() { if (multibootMethod == null) { multibootHeader = Linker.CreateSymbol(MultibootHeaderSymbolName, SectionKind.Text, 1, 0x30); multibootMethod = Compiler.CreateLinkerMethod("MultibootInit"); Linker.EntryPoint = Linker.GetSymbol(multibootMethod.FullName, SectionKind.Text); WriteMultibootHeader(); return; } var typeInitializerSchedulerStage = Compiler.Pipeline.FindFirst<TypeInitializerSchedulerStage>(); var ecx = Operand.CreateCPURegister(TypeSystem.BuiltIn.I4, GeneralPurposeRegister.ECX); var eax = Operand.CreateCPURegister(TypeSystem.BuiltIn.I4, GeneralPurposeRegister.EAX); var ebx = Operand.CreateCPURegister(TypeSystem.BuiltIn.I4, GeneralPurposeRegister.EBX); var ebp = Operand.CreateCPURegister(TypeSystem.BuiltIn.I4, GeneralPurposeRegister.EBP); var basicBlocks = new BasicBlocks(); var instructionSet = new InstructionSet(25); var ctx = instructionSet.CreateNewBlock(basicBlocks); basicBlocks.AddHeaderBlock(ctx.BasicBlock); // set sentinal on the stack to indicate the start of the stack var zero = Operand.CreateConstant(TypeSystem.BuiltIn.I4, 0); ctx.AppendInstruction(X86.Mov, Operand.CreateMemoryAddress(TypeSystem.BuiltIn.I4, ebp, 0), zero); // store multiboot registers eax and ebx at 0x200000 and 0x200004 respectively ctx.AppendInstruction(X86.Mov, ecx, Operand.CreateConstantSignedInt(TypeSystem, 0x200000)); ctx.AppendInstruction(X86.Mov, Operand.CreateMemoryAddress(TypeSystem.BuiltIn.I4, ecx, 0), eax); ctx.AppendInstruction(X86.Mov, Operand.CreateMemoryAddress(TypeSystem.BuiltIn.I4, ecx, 4), ebx); // call type initializer var entryPoint = Operand.CreateSymbolFromMethod(TypeSystem, typeInitializerSchedulerStage.TypeInitializerMethod); ctx.AppendInstruction(X86.Call, null, entryPoint); // should never get here ctx.AppendInstruction(X86.Ret); Compiler.CompileMethod(multibootMethod, basicBlocks, instructionSet); }
protected override void Run() { // No CIL decoding if this is a linker generated method if (MethodCompiler.Method.IsLinkerGenerated) { return; } var plugMethod = MethodCompiler.Compiler.PlugSystem.GetPlugMethod(MethodCompiler.Method); if (plugMethod != null) { var plugSymbol = Operand.CreateSymbolFromMethod(TypeSystem, plugMethod); var context = CreateNewBlockContext(-1); context.AppendInstruction(IRInstruction.Jmp, null, plugSymbol); BasicBlocks.AddHeaderBlock(context.Block); return; } if (MethodCompiler.Method.Code.Count == 0) { if (DelegatePatcher.PatchDelegate(MethodCompiler)) { return; } MethodCompiler.Stop(); return; } MethodCompiler.SetLocalVariables(MethodCompiler.Method.LocalVariables); // Create the prologue block var prologue = CreateNewBlock(BasicBlock.PrologueLabel); BasicBlocks.AddHeaderBlock(prologue); var jmpNode = new InstructionNode(); jmpNode.Label = BasicBlock.PrologueLabel; jmpNode.Block = prologue; prologue.First.Insert(jmpNode); // Create starting block var startBlock = CreateNewBlock(0); jmpNode.SetInstruction(IRInstruction.Jmp, startBlock); DecodeInstructionTargets(); DecodeProtectedRegionTargets(); /* Decode the instructions */ DecodeInstructions(); foreach (var block in BasicBlocks) { if (!block.HasPreviousBlocks && !BasicBlocks.HeadBlocks.Contains(block)) { // block was targeted (probably by an leave instruction within a protected region) BasicBlocks.AddHeaderBlock(block); } } // This makes it easier to review --- it's not necessary BasicBlocks.OrderByLabel(); }
protected override void Run() { if (multibootMethod == null) { multibootHeader = Linker.CreateSymbol(MultibootHeaderSymbolName, SectionKind.Text, 1, 0x30); multibootMethod = Compiler.CreateLinkerMethod("MultibootInit"); Linker.EntryPoint = Linker.GetSymbol(multibootMethod.FullName, SectionKind.Text); WriteMultibootHeader(); Linker.CreateSymbol(MultibootEAX, SectionKind.BSS, Architecture.NativeAlignment, Architecture.NativePointerSize); Linker.CreateSymbol(MultibootEBX, SectionKind.BSS, Architecture.NativeAlignment, Architecture.NativePointerSize); return; } var typeInitializerSchedulerStage = Compiler.PostCompilePipeline.FindFirst<TypeInitializerSchedulerStage>(); var ecx = Operand.CreateCPURegister(TypeSystem.BuiltIn.I4, GeneralPurposeRegister.ECX); var eax = Operand.CreateCPURegister(TypeSystem.BuiltIn.I4, GeneralPurposeRegister.EAX); var ebx = Operand.CreateCPURegister(TypeSystem.BuiltIn.I4, GeneralPurposeRegister.EBX); var ebp = Operand.CreateCPURegister(TypeSystem.BuiltIn.I4, GeneralPurposeRegister.EBP); var multibootEax = Operand.CreateUnmanagedSymbolPointer(TypeSystem, MultibootEAX); var multibootEbx = Operand.CreateUnmanagedSymbolPointer(TypeSystem, MultibootEBX); var basicBlocks = new BasicBlocks(); var block = basicBlocks.CreateBlock(); basicBlocks.AddHeaderBlock(block); var ctx = new Context(block); // set sentinel on the stack to indicate the start of the stack var zero = Operand.CreateConstant(TypeSystem.BuiltIn.I4, 0); ctx.AppendInstruction(X86.Mov, Operand.CreateMemoryAddress(TypeSystem.BuiltIn.I4, ebp, 0), zero); ctx.AppendInstruction(X86.Mov, ecx, multibootEax); ctx.AppendInstruction(X86.Mov, Operand.CreateMemoryAddress(TypeSystem.BuiltIn.I4, ecx, 0), eax); ctx.AppendInstruction(X86.Mov, ecx, multibootEbx); ctx.AppendInstruction(X86.Mov, Operand.CreateMemoryAddress(TypeSystem.BuiltIn.I4, ecx, 0), ebx); // call type initializer var entryPoint = Operand.CreateSymbolFromMethod(TypeSystem, typeInitializerSchedulerStage.TypeInitializerMethod); ctx.AppendInstruction(X86.Call, null, entryPoint); // should never get here ctx.AppendInstruction(X86.Ret); Compiler.CompileMethod(multibootMethod, basicBlocks, 0); }