需要一种方法来处理 C# 汇编程序中的 2/3 字节 VEX

Need a way to handle the 2/3 byte VEX in C# assembler

你好,我已经将 x86 汇编程序(和自动汇编程序)从作弊引擎完全移植到 c#。

大部分情况下一切正常,但“VEX”前缀指令目前已损坏。

有两段代码我还不能转换,所以我想知道是否有人可以提供解决方案。

注释掉的部分是我不确定如何处理的部分。

2 字节烦恼

//2byte vex
bytes.SetLength(bytes.Length + 2);
for (i = bytes.Length - 1; i >= RexPrefixLocation + 2; i--)
    bytes[i] = bytes[i - 2];
bytes[RexPrefixLocation] = 0xc5; //2 byte VEX
//pvex2byte(&bytes[RexPrefixLocation + 1])->pp = (int) (Assembler.OpCodes[j].VexLeadingOpCode);
//pvex2byte(&bytes[RexPrefixLocation + 1])->l = Assembler.OpCodes[j].VexL;
//pvex2byte(&bytes[RexPrefixLocation + 1])->vvvv = vexvvvv;
//pvex2byte(&bytes[RexPrefixLocation + 1])->r = RexR ? 0 : 1;
if (RelativeAddressLocation != -1)
    RelativeAddressLocation += 2;

3 字节烦恼

//3byte vex
bytes.SetLength(bytes.Length + 3);
for (i = bytes.Length - 1; i >= RexPrefixLocation + 3; i--)
    bytes[i] = bytes[i - 3];
bytes[RexPrefixLocation] = 0xc4; //3 byte VEX
//pvex3byte(&bytes[RexPrefixLocation + 1])->mmmmm = (int)(Assembler.OpCodes[j].VexLeadingOpCode);
//pvex3byte(&bytes[RexPrefixLocation + 1])->b = RexB ? 0 : 1;
//pvex3byte(&bytes[RexPrefixLocation + 1])->x = RexX ? 0 : 1;
//pvex3byte(&bytes[RexPrefixLocation + 1])->r = RexR ? 0 : 1;
//pvex3byte(&bytes[RexPrefixLocation + 1])->pp = (int)(Assembler.OpCodes[j].VexLeadingOpCode);
//pvex3byte(&bytes[RexPrefixLocation + 1])->l = Assembler.OpCodes[j].VexL;
//pvex3byte(&bytes[RexPrefixLocation + 1])->vvvv = vexvvvv;
//pvex3byte(&bytes[RexPrefixLocation + 1])->w = RexW ? 1 : 0; //not inverted
if (RelativeAddressLocation != -1)
    RelativeAddressLocation += 3;

最初的assembly/auto汇编器是用pascal (lazarus)编写的,这里是pvex3byte

的定义
  TVEX3Byte=bitpacked record
    mmmmm: 0..31;
    B: 0..1;
    X: 0..1;
    R: 0..1;
    pp: 0..3;
    L: 0..1;
    vvvv: 0..15;
    W: 0..1;
  end;
  PVEX3Byte=^TVEX3Byte;

  TVEX2Byte=bitpacked record
    pp: 0..3;
    L: 0..1;
    vvvv: 0..15;
    R: 0..1;
  end;
  PVex2Byte=^TVex2Byte;

有人能解决这部分怎么填吗?如果可能,完整的 class 或“字节”(byte[]) 数组的扩展,以允许 editing/reading 正确处理这些问题?

我认为它与位有关,不幸的是,c# 中没有位结构(none 以这种方式工作)。

在 github

上找到这个
    /* VEX 2 byte form */
    /*  7                           0    */
    /* +---+---+---+---+---+---+---+---+ */
    /* |~R |     ~vvvv     | L |   pp  | */
    /* +---+---+---+---+---+---+---+---+ */

    /* VEX 3 byte form */
    /*   7                           0     7                           0    */
    /* +---+---+---+---+---+---+---+---+   +---+---+---+---+---+---+---+---+*/
    /* |~R |~X |~B | map_select        |   |W/E|    ~vvvv      | L |   pp  |*/
    /* +---+---+---+---+---+---+---+---+   +---+---+---+---+---+---+---+---+*/

然后朋友的帮助和我的自定义 vec() class 很快就解决了这个问题。

最终结果是一个新的多字节 class 可以处理具有简单属性的 vex2/3。

    public class AVex3Byte : AMultiByte
    {
        #region Constants
        private const int SIZE = 2;
        #endregion
        #region R
        public Byte R
        {
            get => (Byte)Get(7, 1, true);
            set
            {
                Set(7, 1, true, value);
                Apply();
            }
        }
        #endregion
        #region X
        public Byte X
        {
            get => (Byte)Get(6, 1, true);
            set
            {
                Set(6, 1, true, value);
                Apply();
            }
        }
        #endregion
        #region B
        public Byte B
        {
            get => (Byte)Get(5, 1, true);
            set
            {
                Set(5, 1, true, value);
                Apply();
            }
        }
        #endregion
        #region Mmmmm
        public Byte Mmmmm
        {
            get => (Byte)Get(0, 5, true);
            set
            {
                Set(0, 5, true, value);
                Apply();
            }
        }
        #endregion
        #region W
        public Byte W
        {
            get => (Byte)Get(15, 1, true);
            set
            {
                Set(15, 1, true, value);
                Apply();
            }
        }
        #endregion
        #region Vvvv
        public Byte Vvvv
        {
            get => (Byte)Get(11, 4, true);
            set
            {
                Set(11, 4, true, value);
                Apply();
            }
        }
        #endregion
        #region L
        public Byte L
        {
            get => (Byte)Get(10, 1, true);
            set
            {
                Set(10, 1, true, value);
                Apply();
            }
        }
        #endregion
        #region Pp
        public Byte Pp
        {
            get => (Byte)Get(8, 2, true);
            set
            {
                Set(8, 2, true, value);
                Apply();
            }
        }
        #endregion
        #region Constructor
        public AVex3Byte()
            : base(SIZE)
        {
        }
        public AVex3Byte(AByteArray bytes, int index)
            : base(SIZE, bytes, index)
        {
        }
        public AVex3Byte(IntPtr bytesPointer)
            : base(SIZE, bytesPointer, 0)
        {
        }
        public AVex3Byte(IntPtr bytesPointer, int index)
            : base(SIZE, bytesPointer, index)
        {
        }
        #endregion
    }

这是原始问题代码修复后的样子

//2byte vex
bytes.SetLength(bytes.Length + 2);
for (i = bytes.Length - 1; i >= RexPrefixLocation + 2; i--)
    bytes[i] = bytes[i - 2];
bytes[RexPrefixLocation] = 0xc5; //2 byte VEX
var vex2 = new AVex2Byte(bytes, RexPrefixLocation + 1);
vex2.Pp = (Byte)Assembler.OpCodes[j].VexLeadingOpCode;
vex2.L = Assembler.OpCodes[j].VexL;
vex2.Vvvv = (Byte)vexvvvv;
vex2.R = (Byte)(RexR ? 0 : 1);
if (RelativeAddressLocation != -1)
    RelativeAddressLocation += 2;
//3byte vex
bytes.SetLength(bytes.Length + 3);
for (i = bytes.Length - 1; i >= RexPrefixLocation + 3; i--)
    bytes[i] = bytes[i - 3];
bytes[RexPrefixLocation] = 0xc4; //3 byte VEX
var vex3 = new AVex3Byte(bytes, RexPrefixLocation + 1);
vex3.Mmmmm = (Byte)(Assembler.OpCodes[j].VexLeadingOpCode);
vex3.B = (Byte)(RexB ? 0 : 1);
vex3.X = (Byte)(RexX ? 0 : 1); 
vex3.R = (Byte)(RexR ? 0 : 1);
vex3.Pp = (Byte)(Assembler.OpCodes[j].VexLeadingOpCode);
vex3.L = Assembler.OpCodes[j].VexL;
vex3.Vvvv = (Byte)vexvvvv;
vex3.W = (Byte)(RexW ? 1 : 0); //not inverted
if (RelativeAddressLocation != -1)
    RelativeAddressLocation += 3;

我需要的是关于哪些位、它们在哪里、它们有多大以及如何 read/write to/from 的正确信息。