Cosmos is written in C#. Cosmos developers including kernel developers stay in C#. However our IL2CPU libraries have to deal with assembly, and the few of us who deal with the compiler code of course muck about with X86. Previously we had our own class based "inline compiler". It worked reasonably well, but I always wanted something more. Finally I took the time, and I am affectionately calling it X# (from X86).
The idea is to keep all of our source in one place, and keep things very type safe. Our previous class based inline compiler did that. Typical code looked something like this:
using (var xDumbAssembler = new DumbAssembler()) {
new Move(Registers.DX, (xComAddr + 1).ToString());
new Move(Registers.AL, 0.ToString());
new Out("dx", "al");// disable all interrupts
new Move(Registers.DX, (xComAddr + 3).ToString());
new Move(Registers.AL, 0x80.ToString());
new Out("dx", "al");// Enable DLAB (set baud rate divisor)
new Move(Registers.DX, (xComAddr + 0).ToString());
new Move(Registers.AL, 0x1.ToString());
new Out("dx", "al");// Set diviso (low byte)
new Move(Registers.DX, (xComAddr + 1).ToString());
new Move(Registers.AL, 0x00.ToString());
new Out("dx", "al");// // set divisor (high byte)
Its type safe, and not too bad to read. However compare that now with X#:
public void DebugStub(TextWriter aOutputWriter, UInt16 aComAddr) {
UInt16 xComStatusAddr = (UInt16)(aComAddr + 5);
Label = "WriteByteToComPort";
Label = "WriteByteToComPort_Wait";
DX = xComStatusAddr;
AL = Port[DX];
AL.Test(0x20);
JumpIfEqual("WriteByteToComPort_Wait");
DX = aComAddr;
AL = Memory[ESP + 4];
Port[DX] = AL;
Return(4);
Label = "DebugWriteEIP";
AL = Memory[EBP + 3];
EAX.Push();
Call("WriteByteToComPort");
AL = Memory[EBP + 2];
EAX.Push();
Call("WriteByteToComPort");
AL = Memory[EBP + 1];
EAX.Push();
Call("WriteByteToComPort");
AL = Memory[EBP];
EAX.Push();
Call("WriteByteToComPort");
Return();
It's actually all C# and compilable. When it executes, the execution of these statements cause it to output X86 code which can then be built using an assembler. How is it done? We'll very similarly to how I did SQL in C# before LINQ came along.