C# 什么被认为是;自然线形“;操作码。Ldobj?
我正在玩“Reflection.Emit”,希望生成一个静态类,该类在C#中公开一个具有此签名的方法: 我希望这些方法能产生如下结果:C# 什么被认为是;自然线形“;操作码。Ldobj?,c#,alignment,cil,opcode,C#,Alignment,Cil,Opcode,我正在玩“Reflection.Emit”,希望生成一个静态类,该类在C#中公开一个具有此签名的方法: 我希望这些方法能产生如下结果: { // CopyDef ldarg.0 ldarg.1 ldobj Def stobj Def ret } { // CopySeq ldarg.0 ldarg.1 unaligned. 1 ldobj Seq unaligned. 1 stobj Seq ret } 相
{ // CopyDef
ldarg.0
ldarg.1
ldobj Def
stobj Def
ret
}
{ // CopySeq
ldarg.0
ldarg.1
unaligned. 1
ldobj Seq
unaligned. 1
stobj Seq
ret
}
相反,Seq的输出与Def相同,即没有未对齐的x操作码。我希望ldobj/stobj将除自然机器对齐(例如8/4)之外的任何内容都视为未对齐,但我显然错了
我的问题和后续问题:
由于ldobj/stobj操作码必须指定其操作的地址类型,因此“Pack=1”是否以某种方式隐式地“注意到”
如果是这种情况,这是否意味着只要地址不引用小于4的偏移量(例如2,1),带有“Pack=4”的结构就被隐式“处理”,在这种情况下,操作码前面必须有未对齐的x?当然,这只会在初始方法签名中使用非托管指针时发生
更新:
从Opcode.Ldind_I4 MSDN(1)中:
所有ldind指令都是指定相应内置值类的Ldobj指令的快捷方式
来自操作码。未对齐的MSDN(2):
未对齐指定地址。。。堆栈上的数据可能与紧随其后的ldind、stind、。。。ldobj,stobj。。。指示也就是说,对于Ldind_I4指令,地址的对齐可能不是4字节边界
来自操作码Ldobj MSDN(3):
复制的字节数取决于类的大小(由class参数指定)。类参数是表示值类型的元数据标记
从Opcode.Ldind_I4 MSDN(4)中:
返回地址(例如,Ldloca和Ldarga)的所有MSIL指令的结果都是安全对齐的
这表明:
int offset = sizeof(myStruct) & 7; // 3 for 32bit
// offset == 0 -> correct
// offset == 1,3,7 -> unaligned. 1
// offset == 2,6 -> unaligned. 2
// offset == 4 -> unaligned. 4
Seq的大小是9,这给了我们7的偏移量,这意味着我们(最坏的情况)未对齐1
以下CopySeq方法不会生成未对齐的操作码
static void CopySeq(ref Seq dest, Seq[] src) { dest = src[1]; }
{ // CopySeq
ldarg.0
ldarg.1
ldc.i4.1
ldelema Seq
ldobj Seq
stobj Seq
ret
}
除非ldelema对后续的ldobj施展了魔法,否则ldobj应该知道如何处理指定类型的数组中可能出现的任何未对齐,这可以由该类型的大小确定。结构没有未对齐。结构中的某个字段可能未对齐并不重要。@HansPassant如果结构位于seqArr[1]的数组中,它会不会未对齐,因为sizeof(Seq)是9,第二项将直接位于其后?您不使用ldobj直接加载数组元素,而是使用ldelema。@HansPassant我知道ldelema。我想说的是,CopySeq的调用方可以传递seqArr[]的两个任意索引中的两个项。这两个项目中的任何一个都可能未对齐,甚至有不同的偏移。这不是真的吗?
int offset = sizeof(myStruct) & 7; // 3 for 32bit
// offset == 0 -> correct
// offset == 1,3,7 -> unaligned. 1
// offset == 2,6 -> unaligned. 2
// offset == 4 -> unaligned. 4
static void CopySeq(ref Seq dest, Seq[] src) { dest = src[1]; }
{ // CopySeq
ldarg.0
ldarg.1
ldc.i4.1
ldelema Seq
ldobj Seq
stobj Seq
ret
}