mirror of
https://github.com/creeperlv/SVM.git
synced 2026-01-10 20:39:54 +00:00
Jump and Call are working as intended.
This commit is contained in:
@@ -3,8 +3,10 @@ text0 "Hello, World!\n"
|
||||
file_name "example.txt"
|
||||
.code:
|
||||
sd.int32 $4 123
|
||||
write_file:
|
||||
sd.int32 $20 -4
|
||||
sd.int64 $20 label0
|
||||
jmp 20
|
||||
write_file:
|
||||
sd.int32 $10 file_name
|
||||
sd.int32 $11 11
|
||||
sd.int32 $12 1
|
||||
@@ -13,6 +15,9 @@ sd.int32 $11 text0
|
||||
sd.int32 $12 14
|
||||
sys 4
|
||||
return
|
||||
label0:
|
||||
sd.int64 $20 write_file
|
||||
call 20
|
||||
sd.int32 $10 100
|
||||
sys 1
|
||||
bmath add Int32 $4 $5 $6
|
||||
|
||||
@@ -60,6 +60,7 @@ namespace SVM.Advanced.BSDStyleVM
|
||||
public static void __exit(SimpleVirtualMachine machine)
|
||||
{
|
||||
var status = machine.registers.GetData<int>(10);
|
||||
Console.WriteLine($"Bye with {status}.");
|
||||
Environment.Exit(status);
|
||||
}
|
||||
public unsafe static void __open(SimpleVirtualMachine machine)
|
||||
@@ -81,7 +82,7 @@ namespace SVM.Advanced.BSDStyleVM
|
||||
var stream = File.Open(fn, fm, fa);
|
||||
FileDescripter fd = new FileDescripter(stream);
|
||||
w.FDs.Add(fdID, fd);
|
||||
machine.registers.SetDataInRegister<int>(10,fdID);
|
||||
machine.registers.SetDataInRegister<int>(10, fdID);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -97,7 +98,9 @@ namespace SVM.Advanced.BSDStyleVM
|
||||
var size = machine.registers.GetData<ulong>(12);
|
||||
if (w.FDs.TryGetValue(fd, out var descripter))
|
||||
{
|
||||
Console.Write("\"");
|
||||
Console.OpenStandardOutput().WriteData(machine.GetPointer(ptr), size);
|
||||
Console.WriteLine($"\">>{fd}");
|
||||
descripter.stream.WriteData(machine.GetPointer(ptr), size);
|
||||
descripter.stream.Flush();
|
||||
}
|
||||
|
||||
@@ -18,8 +18,8 @@ Register \${D}+
|
||||
LabelCode \.code\:
|
||||
LabelData \.data\:
|
||||
LabelConst \.const\:
|
||||
word [\w\d\.]+
|
||||
GenericLabel {word}\:
|
||||
word [\w\d\.]+
|
||||
LineEnd \n
|
||||
string ""\"".*\""""
|
||||
Number \d+
|
||||
@@ -133,7 +133,7 @@ LabelConstant InternalLbl
|
||||
}
|
||||
if (!item.AllowedTokenIds.Contains(next.Result.LexSegmentId))
|
||||
{
|
||||
operationResult.AddError(new ErrorWMsg($"Token: {LexDef.Content ?? "<null>"} is not allowed here.", LexDef));
|
||||
operationResult.AddError(new ErrorWMsg($"Token: {LexDef.Content ?? "<null>"} is not allowed here. Current context:{instructionDef.Id}", LexDef));
|
||||
return operationResult;
|
||||
}
|
||||
intermediateInstruction.Parameters.Add(next.Result);
|
||||
|
||||
@@ -61,6 +61,10 @@ namespace SVM.Assembler.Core
|
||||
}
|
||||
else
|
||||
{
|
||||
if (TryParseUInt8(input, context, out registerID))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
if (context.IntermediateObject.TryGetConst(input, out var realStr))
|
||||
{
|
||||
return TryParseRegister(realStr, context, out registerID);
|
||||
|
||||
@@ -21,7 +21,7 @@ namespace SVM.Assembler.Core
|
||||
if (DataOffsets.TryGetValue(label, out offset))
|
||||
{
|
||||
//Don't directly give the length there.
|
||||
offset += (uint)IntermediateObject.DetermineFinalInstructionCount(this) * (uint)sizeof(SVMInstruction)+sizeof(int);
|
||||
offset += (uint)IntermediateObject.DetermineFinalInstructionCount(this) * (uint)sizeof(SVMInstruction) + sizeof(int);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@@ -33,16 +33,18 @@ namespace SVM.Assembler.Core
|
||||
{
|
||||
return true;
|
||||
}
|
||||
int acc=0;
|
||||
for (int i = 0; i < IntermediateObject.instructions.Count; i++)
|
||||
{
|
||||
IntermediateInstruction? item = IntermediateObject.instructions[i];
|
||||
if (item.Label != null)
|
||||
if (item.Label.Content == label)
|
||||
{
|
||||
this.label.Add(label, i);
|
||||
offset = i;
|
||||
this.label.Add(label, acc);
|
||||
offset = acc;
|
||||
return true;
|
||||
}
|
||||
acc += Definition.InstructionDefinitions[item.InstDefID].InstructionCount;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -52,7 +52,7 @@
|
||||
</InstructionParameter>
|
||||
</Parameters>
|
||||
</InstructionDefinition>
|
||||
<InstructionDefinition Id="std.int32" PrimaryInstruction="SD" InstructionCount="2">
|
||||
<InstructionDefinition Id="sd.int32" PrimaryInstruction="SD" InstructionCount="2">
|
||||
<Aliases>
|
||||
<Alias Name="sd.int"/>
|
||||
<Alias Name="sd.int32"/>
|
||||
@@ -112,7 +112,7 @@
|
||||
</InstructionParameter>
|
||||
</Parameters>
|
||||
</InstructionDefinition>
|
||||
<InstructionDefinition Id="call" PrimaryInstruction="Call" InstructionCount="2">
|
||||
<InstructionDefinition Id="call" PrimaryInstruction="Call" InstructionCount="1">
|
||||
<Aliases>
|
||||
<Alias Name="call"/>
|
||||
<Alias Name="c"/>
|
||||
@@ -122,8 +122,49 @@
|
||||
<MatchingItems>
|
||||
<Item Id="Number"/>
|
||||
<Item Id="Word"/>
|
||||
<Item Id="Register"/>
|
||||
</MatchingItems>
|
||||
<ExpectedValue Type="Int64" Pos="8" Converter="Integer64" />
|
||||
<ExpectedValue Type="UInt8" Pos="1" Converter="Register" />
|
||||
</InstructionParameter>
|
||||
</Parameters>
|
||||
</InstructionDefinition>
|
||||
<InstructionDefinition Id="jmp" PrimaryInstruction="JMP" InstructionCount="1">
|
||||
<Aliases>
|
||||
<Alias Name="j"/>
|
||||
<Alias Name="jmp"/>
|
||||
</Aliases>
|
||||
<Parameters>
|
||||
<InstructionParameter>
|
||||
<MatchingItems>
|
||||
<Item Id="Number"/>
|
||||
<Item Id="Word"/>
|
||||
<Item Id="Register"/>
|
||||
</MatchingItems>
|
||||
<ExpectedValue Type="UInt8" Pos="1" Converter="Register" />
|
||||
</InstructionParameter>
|
||||
</Parameters>
|
||||
</InstructionDefinition>
|
||||
<InstructionDefinition Id="jif" PrimaryInstruction="JIF" InstructionCount="1">
|
||||
<Aliases>
|
||||
<Alias Name="jif"/>
|
||||
<Alias Name="jf"/>
|
||||
<Alias Name="jmpif"/>
|
||||
</Aliases>
|
||||
<Parameters>
|
||||
<InstructionParameter>
|
||||
<MatchingItems>
|
||||
<Item Id="Number"/>
|
||||
<Item Id="Word"/>
|
||||
<Item Id="Register"/>
|
||||
</MatchingItems>
|
||||
<ExpectedValue Type="UInt8" Pos="1" Converter="Register" />
|
||||
</InstructionParameter>
|
||||
<InstructionParameter>
|
||||
<MatchingItems>
|
||||
<Item Id="Number"/>
|
||||
<Item Id="Word"/>
|
||||
</MatchingItems>
|
||||
<ExpectedValue Type="UInt8" Pos="2" Converter="UInt8" />
|
||||
</InstructionParameter>
|
||||
</Parameters>
|
||||
</InstructionDefinition>
|
||||
@@ -133,13 +174,6 @@
|
||||
<Alias Name="ret"/>
|
||||
</Aliases>
|
||||
<Parameters>
|
||||
<InstructionParameter>
|
||||
<MatchingItems>
|
||||
<Item Id="Number"/>
|
||||
<Item Id="Word"/>
|
||||
</MatchingItems>
|
||||
<ExpectedValue Type="Int32" Pos="4" Converter="Integer32" />
|
||||
</InstructionParameter>
|
||||
</Parameters>
|
||||
</InstructionDefinition>
|
||||
<InstructionDefinition Id="load" PrimaryInstruction="Load" InstructionCount="1">
|
||||
@@ -200,34 +234,5 @@
|
||||
</InstructionParameter>
|
||||
</Parameters>
|
||||
</InstructionDefinition>
|
||||
<InstructionDefinition Id="load" PrimaryInstruction="Save" InstructionCount="1">
|
||||
<Aliases>
|
||||
<Alias Name="load"/>
|
||||
<Alias Name="ld"/>
|
||||
</Aliases>
|
||||
<Parameters>
|
||||
<InstructionParameter>
|
||||
<MatchingItems>
|
||||
<Item Id="Register"/>
|
||||
<Item Id="Word"/>
|
||||
</MatchingItems>
|
||||
<ExpectedValue Type="UInt8" Pos="1" Converter="Register" />
|
||||
</InstructionParameter>
|
||||
<InstructionParameter>
|
||||
<MatchingItems>
|
||||
<Item Id="Number"/>
|
||||
<Item Id="Word"/>
|
||||
</MatchingItems>
|
||||
<ExpectedValue Type="UInt8" Pos="2" Converter="UInt8" />
|
||||
</InstructionParameter>
|
||||
<InstructionParameter>
|
||||
<MatchingItems>
|
||||
<Item Id="Register"/>
|
||||
<Item Id="Word"/>
|
||||
</MatchingItems>
|
||||
<ExpectedValue Type="UInt8" Pos="3" Converter="Register" />
|
||||
</InstructionParameter>
|
||||
</Parameters>
|
||||
</InstructionDefinition>
|
||||
</Definitions>
|
||||
</ISARoot>
|
||||
@@ -75,6 +75,10 @@ namespace SVM.Assembler
|
||||
if (fResult.HasError())
|
||||
{
|
||||
Console.Error.WriteLine("Finalizer error!");
|
||||
foreach (var item in fResult.Errors)
|
||||
{
|
||||
Console.Error.WriteLine(item.ToString());
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (fResult.Result == null)
|
||||
|
||||
@@ -26,12 +26,11 @@
|
||||
SD,
|
||||
|
||||
// 0 1
|
||||
// JMP RD
|
||||
// [I]Address (int32)
|
||||
// JMP [R]TargetPC
|
||||
JMP,
|
||||
// Jump And Link If Conditional Register is set.
|
||||
// JIF RD FlagID
|
||||
// [I]Address (int32)
|
||||
// Jump If Conditional Register is set.
|
||||
// 0 1 2
|
||||
// JIF [R]TargetPC [I]FlagID
|
||||
JIF,
|
||||
// 0 1 2 3
|
||||
// Load [R]Address [I]Len [R]T
|
||||
@@ -39,9 +38,8 @@
|
||||
// 0 1 2 3
|
||||
// Load [R]Src [I]Len [R]TAddr
|
||||
Save,
|
||||
// 0
|
||||
// Call
|
||||
// [I]Address (int64)
|
||||
// 0 1
|
||||
// Call [R]Address
|
||||
Call,
|
||||
// Return
|
||||
Return,
|
||||
@@ -77,7 +75,7 @@
|
||||
Float,
|
||||
Double,
|
||||
}
|
||||
public enum ConditionFlag
|
||||
public enum ConditionFlag : byte
|
||||
{
|
||||
/// <summary>
|
||||
/// Compare Flag
|
||||
|
||||
@@ -77,6 +77,15 @@ namespace SVM.Core
|
||||
}
|
||||
}
|
||||
}
|
||||
public ulong GetPC()
|
||||
{
|
||||
uint PCOffset = 1;
|
||||
if (Config != null)
|
||||
{
|
||||
PCOffset = Config.PCRegisterID;
|
||||
}
|
||||
return registers.GetData<ulong>((int)PCOffset);
|
||||
}
|
||||
public bool isReachBinaryEnd()
|
||||
{
|
||||
uint PCOffset = 1;
|
||||
@@ -214,12 +223,44 @@ namespace SVM.Core
|
||||
var dataPtr = GetPointer(PC);
|
||||
var data = dataPtr.GetData<int>();
|
||||
registers.SetDataInRegister(Reg, data);
|
||||
//Console.WriteLine($"SVM:SD:{data} form PC={PC}");
|
||||
Console.WriteLine($"SVM:SD:{data} to {Reg} form PC={PC}");
|
||||
}
|
||||
break;
|
||||
case PrimaryInstruction.JMP:
|
||||
{
|
||||
var RegisterID = Instruction.GetData<byte>(1);
|
||||
PC = registers.ReadData<ulong>(RegisterID);
|
||||
Console.WriteLine($"Jump to:{PC}");
|
||||
PC--;
|
||||
}
|
||||
break;
|
||||
case PrimaryInstruction.JIF:
|
||||
{
|
||||
var RegisterID = Instruction.GetData<byte>(1);
|
||||
var FlagID = Instruction.GetData<ConditionFlag>(2);
|
||||
bool isSet = false;
|
||||
unsafe
|
||||
{
|
||||
|
||||
switch (FlagID)
|
||||
{
|
||||
case ConditionFlag.CF:
|
||||
isSet = statePtr->CF != 0;
|
||||
break;
|
||||
case ConditionFlag.Of:
|
||||
isSet = statePtr->OF != 0;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (isSet)
|
||||
{
|
||||
|
||||
PC = registers.ReadData<ulong>(RegisterID);
|
||||
PC--;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case PrimaryInstruction.Load:
|
||||
{
|
||||
@@ -248,6 +289,10 @@ namespace SVM.Core
|
||||
{
|
||||
var cfPtr = GetPointer(ReadCallFrameRegisterAsPtr());
|
||||
cfPtr.SetData(PC + 1);
|
||||
var RegisterID = Instruction.GetData<byte>(1);
|
||||
PC = registers.ReadData<ulong>(RegisterID);
|
||||
Console.WriteLine($"Call to:{PC} ({RegisterID})");
|
||||
PC--;
|
||||
}
|
||||
break;
|
||||
case PrimaryInstruction.Return:
|
||||
|
||||
@@ -29,8 +29,17 @@ class Program
|
||||
BSDLikeWrapper wrapper = new BSDLikeWrapper(svm);
|
||||
svm.Init();
|
||||
while (!svm.isReachBinaryEnd())
|
||||
{
|
||||
try
|
||||
{
|
||||
svm.Step();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Console.WriteLine($"Error at:{svm.GetPC()}");
|
||||
Console.WriteLine(e);
|
||||
throw;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,6 +13,11 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SVM.Assembler", "SVM.Assemb
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SVM.Advanced", "SVM.Advanced\SVM.Advanced.csproj", "{F9F2F699-49F7-4427-BA22-B444DD6259FD}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Examples", "Examples", "{B36A84DF-456D-A817-6EDD-3EC3E7F6E11F}"
|
||||
ProjectSection(SolutionItems) = preProject
|
||||
..\examples\hello.s = ..\examples\hello.s
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
|
||||
Reference in New Issue
Block a user