mirror of
https://github.com/danbulant/Cosmos
synced 2026-05-27 14:02:19 +00:00
.
This commit is contained in:
parent
bbb8265166
commit
feef7db59a
1 changed files with 35 additions and 34 deletions
|
|
@ -1,4 +1,4 @@
|
||||||
//#define VMT_DEBUG
|
//#define VMT_DEBUG
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
|
|
@ -21,6 +21,7 @@ using Cosmos.IL2CPU.Plugs;
|
||||||
using Cosmos.IL2CPU.X86.IL;
|
using Cosmos.IL2CPU.X86.IL;
|
||||||
using Mono.Cecil;
|
using Mono.Cecil;
|
||||||
using XSharp.Compiler;
|
using XSharp.Compiler;
|
||||||
|
using static XSharp.Compiler.XSRegisters;
|
||||||
using Add = Cosmos.Assembler.x86.Add;
|
using Add = Cosmos.Assembler.x86.Add;
|
||||||
using Call = Cosmos.Assembler.x86.Call;
|
using Call = Cosmos.Assembler.x86.Call;
|
||||||
using FieldInfo = Cosmos.IL2CPU.X86.IL.FieldInfo;
|
using FieldInfo = Cosmos.IL2CPU.X86.IL.FieldInfo;
|
||||||
|
|
@ -160,14 +161,14 @@ namespace Cosmos.IL2CPU
|
||||||
if (DebugEnabled && StackCorruptionDetection)
|
if (DebugEnabled && StackCorruptionDetection)
|
||||||
{
|
{
|
||||||
// if StackCorruption detection is active, we're also going to emit a stack overflow detection
|
// if StackCorruption detection is active, we're also going to emit a stack overflow detection
|
||||||
XS.Set(XSRegisters.OldToNewRegister(RegistersEnum.EAX), "Before_Kernel_Stack");
|
XS.Set(OldToNewRegister(RegistersEnum.EAX), "Before_Kernel_Stack");
|
||||||
XS.Compare(XSRegisters.OldToNewRegister(RegistersEnum.EAX), XSRegisters.OldToNewRegister(RegistersEnum.ESP));
|
XS.Compare(OldToNewRegister(RegistersEnum.EAX), OldToNewRegister(RegistersEnum.ESP));
|
||||||
new ConditionalJump { Condition = ConditionalTestEnum.LessThan, DestinationLabel = mCurrentMethodLabel + ".StackOverflowCheck_End" };
|
new ConditionalJump { Condition = ConditionalTestEnum.LessThan, DestinationLabel = mCurrentMethodLabel + ".StackOverflowCheck_End" };
|
||||||
new ClearInterruptFlag();
|
new ClearInterruptFlag();
|
||||||
// don't remove the call. It seems pointless, but we need it to retrieve the EIP value
|
// don't remove the call. It seems pointless, but we need it to retrieve the EIP value
|
||||||
new Call { DestinationLabel = mCurrentMethodLabel + ".StackOverflowCheck_GetAddress" };
|
new Call { DestinationLabel = mCurrentMethodLabel + ".StackOverflowCheck_GetAddress" };
|
||||||
new Label(mCurrentMethodLabel + ".StackOverflowCheck_GetAddress");
|
new Label(mCurrentMethodLabel + ".StackOverflowCheck_GetAddress");
|
||||||
XS.Pop(XSRegisters.OldToNewRegister(RegistersEnum.EAX));
|
XS.Pop(OldToNewRegister(RegistersEnum.EAX));
|
||||||
new Mov { DestinationRef = ElementReference.New("DebugStub_CallerEIP"), DestinationIsIndirect = true, SourceReg = RegistersEnum.EAX };
|
new Mov { DestinationRef = ElementReference.New("DebugStub_CallerEIP"), DestinationIsIndirect = true, SourceReg = RegistersEnum.EAX };
|
||||||
new Call { DestinationLabel = "DebugStub_SendStackOverflowOccurred" };
|
new Call { DestinationLabel = "DebugStub_SendStackOverflowOccurred" };
|
||||||
new Halt();
|
new Halt();
|
||||||
|
|
@ -183,18 +184,18 @@ namespace Cosmos.IL2CPU
|
||||||
var xName = DataMember.FilterStringForIncorrectChars("CCTOR_CALLED__" + LabelName.GetFullName(aMethod.MethodBase.DeclaringType));
|
var xName = DataMember.FilterStringForIncorrectChars("CCTOR_CALLED__" + LabelName.GetFullName(aMethod.MethodBase.DeclaringType));
|
||||||
var xAsmMember = new DataMember(xName, (byte)0);
|
var xAsmMember = new DataMember(xName, (byte)0);
|
||||||
Assembler.DataMembers.Add(xAsmMember);
|
Assembler.DataMembers.Add(xAsmMember);
|
||||||
new Compare { DestinationRef = ElementReference.New(xName), DestinationIsIndirect = true, Size = 8, SourceValue = 1 };
|
XS.Compare(xName, 1, destinationIsIndirect: true, size: RegisterSize.Byte8);
|
||||||
new ConditionalJump { Condition = ConditionalTestEnum.Equal, DestinationLabel = ".BeforeQuickReturn" };
|
new ConditionalJump { Condition = ConditionalTestEnum.Equal, DestinationLabel = ".BeforeQuickReturn" };
|
||||||
new Mov { DestinationRef = ElementReference.New(xName), DestinationIsIndirect = true, Size = 8, SourceValue = 1 };
|
XS.Set(xName, 1, destinationIsIndirect: true, size: RegisterSize.Byte8);
|
||||||
new Jump { DestinationLabel = ".AfterCCTorAlreadyCalledCheck" };
|
new Jump { DestinationLabel = ".AfterCCTorAlreadyCalledCheck" };
|
||||||
new Label(".BeforeQuickReturn");
|
new Label(".BeforeQuickReturn");
|
||||||
XS.Set(XSRegisters.OldToNewRegister(RegistersEnum.ECX), 0);
|
XS.Set(OldToNewRegister(RegistersEnum.ECX), 0);
|
||||||
new Return { };
|
new Return { };
|
||||||
new Label(".AfterCCTorAlreadyCalledCheck");
|
new Label(".AfterCCTorAlreadyCalledCheck");
|
||||||
}
|
}
|
||||||
|
|
||||||
XS.Push(XSRegisters.OldToNewRegister(RegistersEnum.EBP));
|
XS.Push(OldToNewRegister(RegistersEnum.EBP));
|
||||||
XS.Set(XSRegisters.OldToNewRegister(RegistersEnum.EBP), XSRegisters.OldToNewRegister(RegistersEnum.ESP));
|
XS.Set(OldToNewRegister(RegistersEnum.EBP), OldToNewRegister(RegistersEnum.ESP));
|
||||||
|
|
||||||
if (DebugMode == DebugMode.Source)
|
if (DebugMode == DebugMode.Source)
|
||||||
{
|
{
|
||||||
|
|
@ -343,7 +344,7 @@ namespace Cosmos.IL2CPU
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
XS.Set(XSRegisters.OldToNewRegister(RegistersEnum.ECX), 0);
|
XS.Set(OldToNewRegister(RegistersEnum.ECX), 0);
|
||||||
var xTotalArgsSize = (from item in aMethod.MethodBase.GetParameters()
|
var xTotalArgsSize = (from item in aMethod.MethodBase.GetParameters()
|
||||||
select (int)ILOp.Align(ILOp.SizeOfType(item.ParameterType), 4)).Sum();
|
select (int)ILOp.Align(ILOp.SizeOfType(item.ParameterType), 4)).Sum();
|
||||||
if (!aMethod.MethodBase.IsStatic)
|
if (!aMethod.MethodBase.IsStatic)
|
||||||
|
|
@ -386,7 +387,7 @@ namespace Cosmos.IL2CPU
|
||||||
var xOffset = GetResultCodeOffset(xReturnSize, (uint)xTotalArgsSize);
|
var xOffset = GetResultCodeOffset(xReturnSize, (uint)xTotalArgsSize);
|
||||||
for (int i = 0; i < ((int)(xReturnSize/4)); i++)
|
for (int i = 0; i < ((int)(xReturnSize/4)); i++)
|
||||||
{
|
{
|
||||||
XS.Pop(XSRegisters.OldToNewRegister(RegistersEnum.EAX));
|
XS.Pop(OldToNewRegister(RegistersEnum.EAX));
|
||||||
new Mov { DestinationReg = RegistersEnum.EBP, DestinationIsIndirect = true, DestinationDisplacement = (int)(xOffset + ((i + 0) * 4)), SourceReg = RegistersEnum.EAX };
|
new Mov { DestinationReg = RegistersEnum.EBP, DestinationIsIndirect = true, DestinationDisplacement = (int)(xOffset + ((i + 0) * 4)), SourceReg = RegistersEnum.EAX };
|
||||||
}
|
}
|
||||||
// extra stack space is the space reserved for example when a "public static int TestMethod();" method is called, 4 bytes is pushed, to make room for result;
|
// extra stack space is the space reserved for example when a "public static int TestMethod();" method is called, 4 bytes is pushed, to make room for result;
|
||||||
|
|
@ -405,13 +406,13 @@ namespace Cosmos.IL2CPU
|
||||||
|
|
||||||
if (xLocalsSize >= 256)
|
if (xLocalsSize >= 256)
|
||||||
{
|
{
|
||||||
XS.Add(XSRegisters.OldToNewRegister(RegistersEnum.ESP), 255);
|
XS.Add(OldToNewRegister(RegistersEnum.ESP), 255);
|
||||||
xLocalsSize -= 255;
|
xLocalsSize -= 255;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (xLocalsSize > 0)
|
if (xLocalsSize > 0)
|
||||||
{
|
{
|
||||||
XS.Add(XSRegisters.OldToNewRegister(RegistersEnum.ESP), xLocalsSize);
|
XS.Add(OldToNewRegister(RegistersEnum.ESP), xLocalsSize);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -419,21 +420,21 @@ namespace Cosmos.IL2CPU
|
||||||
{
|
{
|
||||||
// if debugstub is active, emit a stack corruption detection. at this point EBP and ESP should have the same value.
|
// if debugstub is active, emit a stack corruption detection. at this point EBP and ESP should have the same value.
|
||||||
// if not, we should somehow break here.
|
// if not, we should somehow break here.
|
||||||
XS.Set(XSRegisters.OldToNewRegister(RegistersEnum.EAX), XSRegisters.OldToNewRegister(RegistersEnum.ESP));
|
XS.Set(OldToNewRegister(RegistersEnum.EAX), OldToNewRegister(RegistersEnum.ESP));
|
||||||
XS.Set(XSRegisters.OldToNewRegister(RegistersEnum.EBX), XSRegisters.OldToNewRegister(RegistersEnum.EBP));
|
XS.Set(OldToNewRegister(RegistersEnum.EBX), OldToNewRegister(RegistersEnum.EBP));
|
||||||
XS.Compare(XSRegisters.OldToNewRegister(RegistersEnum.EAX), XSRegisters.OldToNewRegister(RegistersEnum.EBX));
|
XS.Compare(OldToNewRegister(RegistersEnum.EAX), OldToNewRegister(RegistersEnum.EBX));
|
||||||
new ConditionalJump { Condition = ConditionalTestEnum.Equal, DestinationLabel = xLabelExc + "__2" };
|
new ConditionalJump { Condition = ConditionalTestEnum.Equal, DestinationLabel = xLabelExc + "__2" };
|
||||||
new ClearInterruptFlag();
|
new ClearInterruptFlag();
|
||||||
// don't remove the call. It seems pointless, but we need it to retrieve the EIP value
|
// don't remove the call. It seems pointless, but we need it to retrieve the EIP value
|
||||||
new Call { DestinationLabel = xLabelExc + ".MethodFooterStackCorruptionCheck_Break_on_location" };
|
new Call { DestinationLabel = xLabelExc + ".MethodFooterStackCorruptionCheck_Break_on_location" };
|
||||||
new Label(xLabelExc + ".MethodFooterStackCorruptionCheck_Break_on_location");
|
new Label(xLabelExc + ".MethodFooterStackCorruptionCheck_Break_on_location");
|
||||||
XS.Pop(XSRegisters.OldToNewRegister(RegistersEnum.EAX));
|
XS.Pop(OldToNewRegister(RegistersEnum.EAX));
|
||||||
new Mov { DestinationRef = ElementReference.New("DebugStub_CallerEIP"), DestinationIsIndirect = true, SourceReg = RegistersEnum.EAX };
|
new Mov { DestinationRef = ElementReference.New("DebugStub_CallerEIP"), DestinationIsIndirect = true, SourceReg = RegistersEnum.EAX };
|
||||||
new Call { DestinationLabel = "DebugStub_SendStackCorruptionOccurred" };
|
new Call { DestinationLabel = "DebugStub_SendStackCorruptionOccurred" };
|
||||||
new Halt();
|
new Halt();
|
||||||
}
|
}
|
||||||
new Label(xLabelExc + "__2");
|
new Label(xLabelExc + "__2");
|
||||||
XS.Pop(XSRegisters.OldToNewRegister(RegistersEnum.EBP));
|
XS.Pop(OldToNewRegister(RegistersEnum.EBP));
|
||||||
var xRetSize = ((int)xTotalArgsSize) - ((int)xReturnSize);
|
var xRetSize = ((int)xTotalArgsSize) - ((int)xReturnSize);
|
||||||
if (xRetSize < 0)
|
if (xRetSize < 0)
|
||||||
{
|
{
|
||||||
|
|
@ -858,7 +859,7 @@ namespace Cosmos.IL2CPU
|
||||||
var xSize = X86.IL.Call.GetStackSizeToReservate(aTargetMethod.MethodBase);
|
var xSize = X86.IL.Call.GetStackSizeToReservate(aTargetMethod.MethodBase);
|
||||||
if (xSize > 0)
|
if (xSize > 0)
|
||||||
{
|
{
|
||||||
XS.Sub(XSRegisters.OldToNewRegister(RegistersEnum.ESP), xSize);
|
XS.Sub(OldToNewRegister(RegistersEnum.ESP), xSize);
|
||||||
}
|
}
|
||||||
new Call { DestinationLabel = ILOp.GetMethodLabel(aTargetMethod) };
|
new Call { DestinationLabel = ILOp.GetMethodLabel(aTargetMethod) };
|
||||||
var xMethodInfo = aMethod.MethodBase as SysReflection.MethodInfo;
|
var xMethodInfo = aMethod.MethodBase as SysReflection.MethodInfo;
|
||||||
|
|
@ -879,7 +880,7 @@ namespace Cosmos.IL2CPU
|
||||||
}
|
}
|
||||||
for (int i = 0; i < xResultSize / 4; i++)
|
for (int i = 0; i < xResultSize / 4; i++)
|
||||||
{
|
{
|
||||||
XS.Add(XSRegisters.OldToNewRegister(RegistersEnum.ESP), 4);
|
XS.Add(OldToNewRegister(RegistersEnum.ESP), 4);
|
||||||
}
|
}
|
||||||
}, aNextLabel);
|
}, aNextLabel);
|
||||||
}
|
}
|
||||||
|
|
@ -909,8 +910,8 @@ namespace Cosmos.IL2CPU
|
||||||
{
|
{
|
||||||
XS.Comment("---------------------------------------------------------");
|
XS.Comment("---------------------------------------------------------");
|
||||||
new Label(InitVMTCodeLabel);
|
new Label(InitVMTCodeLabel);
|
||||||
XS.Push(XSRegisters.OldToNewRegister(RegistersEnum.EBP));
|
XS.Push(OldToNewRegister(RegistersEnum.EBP));
|
||||||
XS.Set(XSRegisters.OldToNewRegister(RegistersEnum.EBP), XSRegisters.OldToNewRegister(RegistersEnum.ESP));
|
XS.Set(OldToNewRegister(RegistersEnum.EBP), OldToNewRegister(RegistersEnum.ESP));
|
||||||
mSequences = new DebugInfo.SequencePoint[0];
|
mSequences = new DebugInfo.SequencePoint[0];
|
||||||
|
|
||||||
var xSetTypeInfoRef = VTablesImplRefs.SetTypeInfoRef;
|
var xSetTypeInfoRef = VTablesImplRefs.SetTypeInfoRef;
|
||||||
|
|
@ -1166,7 +1167,7 @@ namespace Cosmos.IL2CPU
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
new Label("_END_OF_" + InitVMTCodeLabel);
|
new Label("_END_OF_" + InitVMTCodeLabel);
|
||||||
XS.Pop(XSRegisters.OldToNewRegister(RegistersEnum.EBP));
|
XS.Pop(OldToNewRegister(RegistersEnum.EBP));
|
||||||
new Return();
|
new Return();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1373,8 +1374,8 @@ namespace Cosmos.IL2CPU
|
||||||
// at the time the datamembers for literal strings are created, the type id for string is not yet determined.
|
// at the time the datamembers for literal strings are created, the type id for string is not yet determined.
|
||||||
// for now, we fix this at runtime.
|
// for now, we fix this at runtime.
|
||||||
new Label(InitStringIDsLabel);
|
new Label(InitStringIDsLabel);
|
||||||
XS.Push(XSRegisters.OldToNewRegister(RegistersEnum.EBP));
|
XS.Push(OldToNewRegister(RegistersEnum.EBP));
|
||||||
XS.Set(XSRegisters.OldToNewRegister(RegistersEnum.EBP), XSRegisters.OldToNewRegister(RegistersEnum.ESP));
|
XS.Set(OldToNewRegister(RegistersEnum.EBP), OldToNewRegister(RegistersEnum.ESP));
|
||||||
new Mov { DestinationReg = RegistersEnum.EAX, SourceRef = ElementReference.New(ILOp.GetTypeIDLabel(typeof(String))), SourceIsIndirect = true };
|
new Mov { DestinationReg = RegistersEnum.EAX, SourceRef = ElementReference.New(ILOp.GetTypeIDLabel(typeof(String))), SourceIsIndirect = true };
|
||||||
new Mov { DestinationRef = ElementReference.New("static_field__System_String_Empty"), DestinationIsIndirect = true, SourceRef = ElementReference.New(LdStr.GetContentsArrayName("")) };
|
new Mov { DestinationRef = ElementReference.New("static_field__System_String_Empty"), DestinationIsIndirect = true, SourceRef = ElementReference.New(LdStr.GetContentsArrayName("")) };
|
||||||
|
|
||||||
|
|
@ -1398,12 +1399,12 @@ namespace Cosmos.IL2CPU
|
||||||
new Mov { DestinationRef = ElementReference.New(xDataMember.Name), DestinationIsIndirect = true, SourceReg = RegistersEnum.EAX };
|
new Mov { DestinationRef = ElementReference.New(xDataMember.Name), DestinationIsIndirect = true, SourceReg = RegistersEnum.EAX };
|
||||||
}
|
}
|
||||||
Assembler.WriteDebugVideo("Done");
|
Assembler.WriteDebugVideo("Done");
|
||||||
XS.Pop(XSRegisters.OldToNewRegister(RegistersEnum.EBP));
|
XS.Pop(OldToNewRegister(RegistersEnum.EBP));
|
||||||
new Return();
|
new Return();
|
||||||
|
|
||||||
new Label(CosmosAssembler.EntryPointName);
|
new Label(CosmosAssembler.EntryPointName);
|
||||||
XS.Push(XSRegisters.OldToNewRegister(RegistersEnum.EBP));
|
XS.Push(OldToNewRegister(RegistersEnum.EBP));
|
||||||
XS.Set(XSRegisters.OldToNewRegister(RegistersEnum.EBP), XSRegisters.OldToNewRegister(RegistersEnum.ESP));
|
XS.Set(OldToNewRegister(RegistersEnum.EBP), OldToNewRegister(RegistersEnum.ESP));
|
||||||
new Call { DestinationLabel = InitVMTCodeLabel };
|
new Call { DestinationLabel = InitVMTCodeLabel };
|
||||||
Assembler.WriteDebugVideo("Initializing string IDs.");
|
Assembler.WriteDebugVideo("Initializing string IDs.");
|
||||||
new Call { DestinationLabel = InitStringIDsLabel };
|
new Call { DestinationLabel = InitStringIDsLabel };
|
||||||
|
|
@ -1418,7 +1419,7 @@ namespace Cosmos.IL2CPU
|
||||||
new Label(xCurLabel);
|
new Label(xCurLabel);
|
||||||
X86.IL.Call.DoExecute(Assembler, null, aEntrypoint.DeclaringType.BaseType.GetMethod("Start"), null, xCurLabel, CosmosAssembler.EntryPointName + ".AfterStart", DebugEnabled);
|
X86.IL.Call.DoExecute(Assembler, null, aEntrypoint.DeclaringType.BaseType.GetMethod("Start"), null, xCurLabel, CosmosAssembler.EntryPointName + ".AfterStart", DebugEnabled);
|
||||||
new Label(CosmosAssembler.EntryPointName + ".AfterStart");
|
new Label(CosmosAssembler.EntryPointName + ".AfterStart");
|
||||||
XS.Pop(XSRegisters.OldToNewRegister(RegistersEnum.EBP));
|
XS.Pop(OldToNewRegister(RegistersEnum.EBP));
|
||||||
new Return();
|
new Return();
|
||||||
|
|
||||||
if (ShouldOptimize)
|
if (ShouldOptimize)
|
||||||
|
|
@ -1510,19 +1511,19 @@ namespace Cosmos.IL2CPU
|
||||||
|
|
||||||
// if debugstub is active, emit a stack corruption detection. at this point EBP and ESP should have the same value.
|
// if debugstub is active, emit a stack corruption detection. at this point EBP and ESP should have the same value.
|
||||||
// if not, we should somehow break here.
|
// if not, we should somehow break here.
|
||||||
XS.Set(XSRegisters.OldToNewRegister(RegistersEnum.EAX), XSRegisters.OldToNewRegister(RegistersEnum.ESP));
|
XS.Set(OldToNewRegister(RegistersEnum.EAX), OldToNewRegister(RegistersEnum.ESP));
|
||||||
XS.Set(XSRegisters.OldToNewRegister(RegistersEnum.EBX), XSRegisters.OldToNewRegister(RegistersEnum.EBP));
|
XS.Set(OldToNewRegister(RegistersEnum.EBX), OldToNewRegister(RegistersEnum.EBP));
|
||||||
if (xStackDifference != 0)
|
if (xStackDifference != 0)
|
||||||
{
|
{
|
||||||
XS.Add(XSRegisters.OldToNewRegister(RegistersEnum.EAX), xStackDifference.Value);
|
XS.Add(OldToNewRegister(RegistersEnum.EAX), xStackDifference.Value);
|
||||||
}
|
}
|
||||||
XS.Compare(XSRegisters.OldToNewRegister(RegistersEnum.EAX), XSRegisters.OldToNewRegister(RegistersEnum.EBX));
|
XS.Compare(OldToNewRegister(RegistersEnum.EAX), OldToNewRegister(RegistersEnum.EBX));
|
||||||
new ConditionalJump { Condition = ConditionalTestEnum.Equal, DestinationLabel = xLabel + ".StackCorruptionCheck_End" };
|
new ConditionalJump { Condition = ConditionalTestEnum.Equal, DestinationLabel = xLabel + ".StackCorruptionCheck_End" };
|
||||||
new ClearInterruptFlag();
|
new ClearInterruptFlag();
|
||||||
// don't remove the call. It seems pointless, but we need it to retrieve the EIP value
|
// don't remove the call. It seems pointless, but we need it to retrieve the EIP value
|
||||||
new Call { DestinationLabel = xLabel + ".StackCorruptionCheck_GetAddress" };
|
new Call { DestinationLabel = xLabel + ".StackCorruptionCheck_GetAddress" };
|
||||||
new Label(xLabel + ".StackCorruptionCheck_GetAddress");
|
new Label(xLabel + ".StackCorruptionCheck_GetAddress");
|
||||||
XS.Pop(XSRegisters.OldToNewRegister(RegistersEnum.EAX));
|
XS.Pop(OldToNewRegister(RegistersEnum.EAX));
|
||||||
new Mov { DestinationRef = ElementReference.New("DebugStub_CallerEIP"), DestinationIsIndirect = true, SourceReg = RegistersEnum.EAX };
|
new Mov { DestinationRef = ElementReference.New("DebugStub_CallerEIP"), DestinationIsIndirect = true, SourceReg = RegistersEnum.EAX };
|
||||||
new Call { DestinationLabel = "DebugStub_SendStackCorruptionOccurred" };
|
new Call { DestinationLabel = "DebugStub_SendStackCorruptionOccurred" };
|
||||||
new Halt();
|
new Halt();
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue