I offer an idea for a way to write asm in C#

Jan 25, 2012 at 2:03 PM

Hi!

I looked how plugs are being baked here.

I thought about this, an offer to use another aproach: lets define an interface ICPU and  a special variable like CPU.Current and replace all calls to it with instructions as declared with attributes.

Something like this.

public enum RegisterID
{
    Error = 0,
    AX,
    BX,
    DX
}
    [AttributeUsage(AttributeTargets.Method)]
    public class InstructionAttribute : Attribute
    {
        public OperationID OperationID { get; private set; }
        public ArgumentMode A0Mode { get; private set; }
        public ArgumentMode A1Mode { get; private set; }
        public long A0Value { get; private set; }
        public long A1Value { get; private set; }

        public InstructionAttribute(OperationID id, ArgumentMode a0Mode, ArgumentMode a1Mode)
        {
            OperationID = id;
            A0Mode = a0Mode;
            A1Mode = a1Mode;
        }

        public InstructionAttribute(OperationID id, ArgumentMode a0Mode)
            :this(id, a0Mode, ArgumentMode.None)
        {
        }

        public InstructionAttribute(OperationID id)
            : this(id,  ArgumentMode.None, ArgumentMode.None)
        {
        }

        public InstructionAttribute(OperationID id, RegisterID a0)
            :this(id, ArgumentMode.RegisterID)
        {
            A0Value = (long)a0;
        }

        public InstructionAttribute(OperationID id, RegisterID a0, RegisterID a1)
            : this(id, ArgumentMode.RegisterID, ArgumentMode.RegisterID)
        {
            A0Value = (long)a0;
            A1Value = (long)a1;
        }

        public InstructionAttribute(OperationID id, RegisterID a0, ArgumentMode a1mode)
            : this(id, ArgumentMode.SpecialID, a1mode)
        {
            A0Value = (long)a0;
        }

        public InstructionAttribute(OperationID id, ArgumentMode a0mode, RegisterID a1)
            : this(id, a0mode, ArgumentMode.RegisterID)
        {
            A1Value = (long)a1;
        }


    public enum ArgumentMode : byte
    {
        Error = 0x00,
        None,
        ConstantBit,
        ConstantI8,
        ConstantI16,
        ConstantI32,
        ConstantI64,
        ConstantU8,
        ConstantU16,
        ConstantU32,
        ConstantU64,
        ConstantF32,
        ConstantF64,
        ConstantChar8,
        ConstantChar16,
        RegisterID
    }


    public enum OperationID : byte
    {
        Error = 0x00,
        NOOP,
        PUSH,
        POP,
        MOV,
        CALL,
        GoToIf,
        GoToIfNot,
        GOTO
    }


    public interface IRegisters
    {
        ushort AX { get; set; }
        ushort BX { get; set; }
        ushort DX { get; set; }
    }

    public interface ICPU : IRegisters
    {
           [Instruction(OperationID.NOOP)]
           ICPU NOOP();
           [Instruction(OperationID.PUSH, RegisterID.AX)]
           ICPU PushAX();
           [Instruction(OperationID.PUSH, RegisterID.BX)]
           ICPU PushBX();
           [Instruction(OperationID.POP, RegisterID.AX)]
           ICPU PopAX();
    }

    public static class CPU
    {
         public void ASM(Expression<Action<ICPU>> lmbda)
         {
                //IL2ASM does this
         }
    
         public CodeBlob<TFunc> ASMCompile<TFunc>(Expression<Action<ICPU>> lambda)
         {
                //Lets parse this lambda and generate instructions right now
                //and allow calling of this by IL2ASM who knows that address of CodeBlob first byte of internal byte[] is a callable code address.
         }

    }

Coordinator
Jan 25, 2012 at 2:05 PM
We already have a good way to produce assembly plugs (we call it X#). It's not perfect, but it's being upgraded and improved constantly..


On Wed, Jan 25, 2012 at 3:03 PM, Konstardiy <notifications@codeplex.com> wrote:

From: Konstardiy

Hi!

I looked how plugs are being baked here.

I thought about this, an offer to use another aproach: lets define an interface ICPU and a special variable like CPU.Current and replace all calls to it with instructions as declared with attributes.

Something like this.

public enum RegisterID
{
    Error = 0,
    AX,
    BX,
    DX
}
    [AttributeUsage(AttributeTargets.Method)]
    public class InstructionAttribute : Attribute
    {
        public OperationID OperationID { get; private set; }
        public ArgumentMode A0Mode { get; private set; }
        public ArgumentMode A1Mode { get; private set; }
        public long A0Value { get; private set; }
        public long A1Value { get; private set; }

        public InstructionAttribute(OperationID id, ArgumentMode a0Mode, ArgumentMode a1Mode)
        {
            OperationID = id;
            A0Mode = a0Mode;
            A1Mode = a1Mode;
        }

        public InstructionAttribute(OperationID id, ArgumentMode a0Mode)
            :this(id, a0Mode, ArgumentMode.None)
        {
        }

        public InstructionAttribute(OperationID id)
            : this(id,  ArgumentMode.None, ArgumentMode.None)
        {
        }

        public InstructionAttribute(OperationID id, RegisterID a0)
            :this(id, ArgumentMode.RegisterID)
        {
            A0Value = (long)a0;
        }

        public InstructionAttribute(OperationID id, RegisterID a0, RegisterID a1)
            : this(id, ArgumentMode.RegisterID, ArgumentMode.RegisterID)
        {
            A0Value = (long)a0;
            A1Value = (long)a1;
        }

        public InstructionAttribute(OperationID id, RegisterID a0, ArgumentMode a1mode)
            : this(id, ArgumentMode.SpecialID, a1mode)
        {
            A0Value = (long)a0;
        }

        public InstructionAttribute(OperationID id, ArgumentMode a0mode, RegisterID a1)
            : this(id, a0mode, ArgumentMode.RegisterID)
        {
            A1Value = (long)a1;
        }


    public enum ArgumentMode : byte
    {
        Error = 0x00,
        None,
        ConstantBit,
        ConstantI8,
        ConstantI16,
        ConstantI32,
        ConstantI64,
        ConstantU8,
        ConstantU16,
        ConstantU32,
        ConstantU64,
        ConstantF32,
        ConstantF64,
        ConstantChar8,
        ConstantChar16,
        RegisterID
    }


    public enum OperationID : byte
    {
        Error = 0x00,
        NOOP,
        PUSH,
        POP,
        MOV,
        CALL,
        GoToIf,
        GoToIfNot,
        GOTO
    }


    public interface IRegisters
    {
        ushort AX { get; set; }
        ushort BX { get; set; }
        ushort DX { get; set; }
    }

    public interface ICPU : IRegisters
    {
           [Instruction(OperationID.NOOP)]
           ICPU NOOP();
           [Instruction(OperationID.PUSH, RegisterID.AX)]
           ICPU PushAX();
           [Instruction(OperationID.PUSH, RegisterID.BX)]
           ICPU PushBX();
           [Instruction(OperationID.POP, RegisterID.AX)]
           ICPU PopAX();
    }

    public static class CPU
    {
         public void ASM(Expression<Action<ICPU>> lmbda)
         {
                //IL2ASM does this
         }
    
         public CodeBlob<TFunc> ASMCompile<TFunc>(Expression<Action<ICPU>> lambda)
         {
                //Lets parse this lambda and generate instructions right now
                //and allow calling of this by IL2ASM who knows that address of CodeBlob first byte of internal byte[] is a callable code address.
         }

    }

Read the full discussion online.

To add a post to this discussion, reply to this email (Cosmos@discussions.codeplex.com)

To start a new discussion for this project, email Cosmos@discussions.codeplex.com

You are receiving this email because you subscribed to this discussion on CodePlex. You can unsubscribe or change your settings on codePlex.com.

Please note: Images and attachments will be removed from emails. Any posts to this discussion will also be available online at codeplex.com


Developer
Jan 25, 2012 at 2:09 PM

Don't interfaces not work?

On Jan 25, 2012 7:05 AM, "mterwoord" <notifications@codeplex.com> wrote:

From: mterwoord

We already have a good way to produce assembly plugs (we call it X#). It's not perfect, but it's being upgraded and improved constantly..


On Wed, Jan 25, 2012 at 3:03 PM, Konstardiy <notifications@codeplex.com> wrote:

From: Konstardiy

Hi!

I looked how plugs are being baked here.

I thought about this, an offer to use another aproach: lets define an interface ICPU and a special variable like CPU.Current and replace all calls to it with instructions as declared with attributes.

Something like this.

public enum RegisterID
{
    Error = 0,
    AX,
    BX,
    DX
}
    [AttributeUsage(AttributeTargets.Method)]
    public class InstructionAttribute : Attribute
    {
        public OperationID OperationID { get; private set; }
        public ArgumentMode A0Mode { get; private set; }
        public ArgumentMode A1Mode { get; private set; }
        public long A0Value { get; private set; }
        public long A1Value { get; private set; }

        public InstructionAttribute(OperationID id, ArgumentMode a0Mode, ArgumentMode a1Mode)
        {
            OperationID = id;
            A0Mode = a0Mode;
            A1Mode = a1Mode;
        }

        public InstructionAttribute(OperationID id, ArgumentMode a0Mode)
            :this(id, a0Mode, ArgumentMode.None)
        {
        }

        public InstructionAttribute(OperationID id)
            : this(id,  ArgumentMode.None, ArgumentMode.None)
        {
        }

        public InstructionAttribute(OperationID id, RegisterID a0)
            :this(id, ArgumentMode.RegisterID)
        {
            A0Value = (long)a0;
        }

        public InstructionAttribute(OperationID id, RegisterID a0, RegisterID a1)
            : this(id, ArgumentMode.RegisterID, ArgumentMode.RegisterID)
        {
            A0Value = (long)a0;
            A1Value = (long)a1;
        }

        public InstructionAttribute(OperationID id, RegisterID a0, ArgumentMode a1mode)
            : this(id, ArgumentMode.SpecialID, a1mode)
        {
            A0Value = (long)a0;
        }

        public InstructionAttribute(OperationID id, ArgumentMode a0mode, RegisterID a1)
            : this(id, a0mode, ArgumentMode.RegisterID)
        {
            A1Value = (long)a1;
        }


    public enum ArgumentMode : byte
    {
        Error = 0x00,
        None,
        ConstantBit,
        ConstantI8,
        ConstantI16,
        ConstantI32,
        ConstantI64,
        ConstantU8,
        ConstantU16,
        ConstantU32,
        ConstantU64,
        ConstantF32,
        ConstantF64,
        ConstantChar8,
        ConstantChar16,
        RegisterID
    }


    public enum OperationID : byte
    {
        Error = 0x00,
        NOOP,
        PUSH,
        POP,
        MOV,
        CALL,
        GoToIf,
        GoToIfNot,
        GOTO
    }


    public interface IRegisters
    {
        ushort AX { get; set; }
        ushort BX { get; set; }
        ushort DX { get; set; }
    }

    public interface ICPU : IRegisters
    {
           [Instruction(OperationID.NOOP)]
           ICPU NOOP();
           [Instruction(OperationID.PUSH, RegisterID.AX)]
           ICPU PushAX();
           [Instruction(OperationID.PUSH, RegisterID.BX)]
           ICPU PushBX();
           [Instruction(OperationID.POP, RegisterID.AX)]
           ICPU PopAX();
    }

    public static class CPU
    {
         public void ASM(Expression<Action<ICPU>> lmbda)
         {
                //IL2ASM does this
         }
    
         public CodeBlob<TFunc> ASMCompile<TFunc>(Expression<Action<ICPU>> lambda)
         {
                //Lets parse this lambda and generate instructions right now
                //and allow calling of this by IL2ASM who knows that address of CodeBlob first byte of internal byte[] is a callable code address.
         }

    }

Read the full discussion online.

To add a post to this discussion, reply to this email (Cosmos@discussions.codeplex.com)

To start a new discussion for this project, email Cosmos@discussions.codeplex.com

You are receiving this email because you subscribed to this discussion on CodePlex. You can unsubscribe or change your settings on codePlex.com.

Please note: Images and attachments will be removed from emails. Any posts to this discussion will also be available online at codeplex.com


Read the full discussion online.

To add a post to this discussion, reply to this email (Cosmos@discussions.codeplex.com)

To start a new discussion for this project, email Cosmos@discussions.codeplex.com

You are receiving this email because you subscribed to this discussion on CodePlex. You can unsubscribe or change your settings on codePlex.com.

Please note: Images and attachments will be removed from emails. Any posts to this discussion will also be available online at codeplex.com

Coordinator
Jan 25, 2012 at 2:12 PM
plugs are done compiletime, so that code wouldn't be executed at runtime...
Konstardiy: Besides my previous answer, most plugs should and can be implemented in c# code.

On Wed, Jan 25, 2012 at 3:09 PM, joshbeitler <notifications@codeplex.com> wrote:

From: joshbeitler

Don't interfaces not work?

On Jan 25, 2012 7:05 AM, "mterwoord" <notifications@codeplex.com> wrote:

From: mterwoord

We already have a good way to produce assembly plugs (we call it X#). It's not perfect, but it's being upgraded and improved constantly..


On Wed, Jan 25, 2012 at 3:03 PM, Konstardiy <notifications@codeplex.com> wrote:

From: Konstardiy

Hi!

I looked how plugs are being baked here.

I thought about this, an offer to use another aproach: lets define an interface ICPU and a special variable like CPU.Current and replace all calls to it with instructions as declared with attributes.

Something like this.

public enum RegisterID
{
    Error = 0,
    AX,
    BX,
    DX
}
    [AttributeUsage(AttributeTargets.Method)]
    public class InstructionAttribute : Attribute
    {
        public OperationID OperationID { get; private set; }
        public ArgumentMode A0Mode { get; private set; }
        public ArgumentMode A1Mode { get; private set; }
        public long A0Value { get; private set; }
        public long A1Value { get; private set; }

        public InstructionAttribute(OperationID id, ArgumentMode a0Mode, ArgumentMode a1Mode)
        {
            OperationID = id;
            A0Mode = a0Mode;
            A1Mode = a1Mode;
        }

        public InstructionAttribute(OperationID id, ArgumentMode a0Mode)
            :this(id, a0Mode, ArgumentMode.None)
        {
        }

        public InstructionAttribute(OperationID id)
            : this(id,  ArgumentMode.None, ArgumentMode.None)
        {
        }

        public InstructionAttribute(OperationID id, RegisterID a0)
            :this(id, ArgumentMode.RegisterID)
        {
            A0Value = (long)a0;
        }

        public InstructionAttribute(OperationID id, RegisterID a0, RegisterID a1)
            : this(id, ArgumentMode.RegisterID, ArgumentMode.RegisterID)
        {
            A0Value = (long)a0;
            A1Value = (long)a1;
        }

        public InstructionAttribute(OperationID id, RegisterID a0, ArgumentMode a1mode)
            : this(id, ArgumentMode.SpecialID, a1mode)
        {
            A0Value = (long)a0;
        }

        public InstructionAttribute(OperationID id, ArgumentMode a0mode, RegisterID a1)
            : this(id, a0mode, ArgumentMode.RegisterID)
        {
            A1Value = (long)a1;
        }


    public enum ArgumentMode : byte
    {
        Error = 0x00,
        None,
        ConstantBit,
        ConstantI8,
        ConstantI16,
        ConstantI32,
        ConstantI64,
        ConstantU8,
        ConstantU16,
        ConstantU32,
        ConstantU64,
        ConstantF32,
        ConstantF64,
        ConstantChar8,
        ConstantChar16,
        RegisterID
    }


    public enum OperationID : byte
    {
        Error = 0x00,
        NOOP,
        PUSH,
        POP,
        MOV,
        CALL,
        GoToIf,
        GoToIfNot,
        GOTO
    }


    public interface IRegisters
    {
        ushort AX { get; set; }
        ushort BX { get; set; }
        ushort DX { get; set; }
    }

    public interface ICPU : IRegisters
    {
           [Instruction(OperationID.NOOP)]
           ICPU NOOP();
           [Instruction(OperationID.PUSH, RegisterID.AX)]
           ICPU PushAX();
           [Instruction(OperationID.PUSH, RegisterID.BX)]
           ICPU PushBX();
           [Instruction(OperationID.POP, RegisterID.AX)]
           ICPU PopAX();
    }

    public static class CPU
    {
         public void ASM(Expression<Action<ICPU>> lmbda)
         {
                //IL2ASM does this
         }
    
         public CodeBlob<TFunc> ASMCompile<TFunc>(Expression<Action<ICPU>> lambda)
         {
                //Lets parse this lambda and generate instructions right now
                //and allow calling of this by IL2ASM who knows that address of CodeBlob first byte of internal byte[] is a callable code address.
         }

    }

Read the full discussion online.

To add a post to this discussion, reply to this email (Cosmos@discussions.codeplex.com)

To start a new discussion for this project, email Cosmos@discussions.codeplex.com

You are receiving this email because you subscribed to this discussion on CodePlex. You can unsubscribe or change your settings on codePlex.com.

Please note: Images and attachments will be removed from emails. Any posts to this discussion will also be available online at codeplex.com


Read the full discussion online.

To add a post to this discussion, reply to this email (Cosmos@discussions.codeplex.com)

To start a new discussion for this project, email Cosmos@discussions.codeplex.com

You are receiving this email because you subscribed to this discussion on CodePlex. You can unsubscribe or change your settings on codePlex.com.

Please note: Images and attachments will be removed from emails. Any posts to this discussion will also be available online at codeplex.com

Read the full discussion online.

To add a post to this discussion, reply to this email (Cosmos@discussions.codeplex.com)

To start a new discussion for this project, email Cosmos@discussions.codeplex.com

You are receiving this email because you subscribed to this discussion on CodePlex. You can unsubscribe or change your settings on codePlex.com.

Please note: Images and attachments will be removed from emails. Any posts to this discussion will also be available online at codeplex.com


Coordinator
Jan 25, 2012 at 2:14 PM
> Don't interfaces not work?

His code would run at compile time, not run time so it would be ok.
Coordinator
Jan 25, 2012 at 2:16 PM
We currently have a plan to make plugs easier (the C# classes part)..
but have you seen X#?

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();
Jan 25, 2012 at 2:37 PM

I am sorry, i saw this article: http://www.codeproject.com/Articles/220076/Csharp-Open-Source-Managed-Operating-System-Intro

and was "scared" a bit by the way described there. Well, later i found info about X#...

But what about embedding IL2ASM/X# into core, to make able to create managed drivers, IL2ASM-ed at boot/load time? This will allow to keep OS managed even with growing capabilities and so on...

Coordinator
Jan 25, 2012 at 2:41 PM
drivers should be implemented in full c# code, so they're portable to other architectures in the futures..
if ou're going to write drivers in assembler (whether it's text-assembler, x#-assembler or your option) is going to be a pain-in-the-backside to maintain (if you even get it working..)


On Wed, Jan 25, 2012 at 3:38 PM, konstardiy <notifications@codeplex.com> wrote:

From: konstardiy

I am sorry, i saw this article: http://www.codeproject.com/Articles/220076/Csharp-Open-Source-Managed-Operating-System-Intro

and was "scared" a bit by the way described there. Well, later i found info about X#...

But what about embedding IL2ASM/X# into core, to make able to create managed drivers, IL2ASM-ed at boot/load time? This will allow to keep OS managed even with growing capabilities and so on...

Read the full discussion online.

To add a post to this discussion, reply to this email (Cosmos@discussions.codeplex.com)

To start a new discussion for this project, email Cosmos@discussions.codeplex.com

You are receiving this email because you subscribed to this discussion on CodePlex. You can unsubscribe or change your settings on codePlex.com.

Please note: Images and attachments will be removed from emails. Any posts to this discussion will also be available online at codeplex.com


Coordinator
Jan 25, 2012 at 2:57 PM
On 1/25/2012 10:41 AM, mterwoord wrote:
> drivers should be implemented in full c# code, so they're portable to
> other architectures in the futures..
> if ou're going to write drivers in assembler (whether it's
> text-assembler, x#-assembler or your option) is going to be a
> pain-in-the-backside to maintain (if you even get it working..)

Taht said - teh plan is to convert all our existing code to X#.... but
its just not a priority right now...