需要一种方法来处理 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 的正确信息。
你好,我已经将 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 的正确信息。