Jump and Call are working as intended.

This commit is contained in:
2025-08-15 16:03:14 +10:00
parent 914c6febbe
commit 0069c573e7
11 changed files with 137 additions and 57 deletions

View File

@@ -3,8 +3,10 @@ text0 "Hello, World!\n"
file_name "example.txt" file_name "example.txt"
.code: .code:
sd.int32 $4 123 sd.int32 $4 123
write_file:
sd.int32 $20 -4 sd.int32 $20 -4
sd.int64 $20 label0
jmp 20
write_file:
sd.int32 $10 file_name sd.int32 $10 file_name
sd.int32 $11 11 sd.int32 $11 11
sd.int32 $12 1 sd.int32 $12 1
@@ -13,6 +15,9 @@ sd.int32 $11 text0
sd.int32 $12 14 sd.int32 $12 14
sys 4 sys 4
return return
label0:
sd.int64 $20 write_file
call 20
sd.int32 $10 100 sd.int32 $10 100
sys 1 sys 1
bmath add Int32 $4 $5 $6 bmath add Int32 $4 $5 $6

View File

@@ -60,6 +60,7 @@ namespace SVM.Advanced.BSDStyleVM
public static void __exit(SimpleVirtualMachine machine) public static void __exit(SimpleVirtualMachine machine)
{ {
var status = machine.registers.GetData<int>(10); var status = machine.registers.GetData<int>(10);
Console.WriteLine($"Bye with {status}.");
Environment.Exit(status); Environment.Exit(status);
} }
public unsafe static void __open(SimpleVirtualMachine machine) public unsafe static void __open(SimpleVirtualMachine machine)
@@ -81,7 +82,7 @@ namespace SVM.Advanced.BSDStyleVM
var stream = File.Open(fn, fm, fa); var stream = File.Open(fn, fm, fa);
FileDescripter fd = new FileDescripter(stream); FileDescripter fd = new FileDescripter(stream);
w.FDs.Add(fdID, fd); w.FDs.Add(fdID, fd);
machine.registers.SetDataInRegister<int>(10,fdID); machine.registers.SetDataInRegister<int>(10, fdID);
} }
else else
{ {
@@ -97,7 +98,9 @@ namespace SVM.Advanced.BSDStyleVM
var size = machine.registers.GetData<ulong>(12); var size = machine.registers.GetData<ulong>(12);
if (w.FDs.TryGetValue(fd, out var descripter)) if (w.FDs.TryGetValue(fd, out var descripter))
{ {
Console.Write("\"");
Console.OpenStandardOutput().WriteData(machine.GetPointer(ptr), size); Console.OpenStandardOutput().WriteData(machine.GetPointer(ptr), size);
Console.WriteLine($"\">>{fd}");
descripter.stream.WriteData(machine.GetPointer(ptr), size); descripter.stream.WriteData(machine.GetPointer(ptr), size);
descripter.stream.Flush(); descripter.stream.Flush();
} }

View File

@@ -18,8 +18,8 @@ Register \${D}+
LabelCode \.code\: LabelCode \.code\:
LabelData \.data\: LabelData \.data\:
LabelConst \.const\: LabelConst \.const\:
word [\w\d\.]+
GenericLabel {word}\: GenericLabel {word}\:
word [\w\d\.]+
LineEnd \n LineEnd \n
string ""\"".*\"""" string ""\"".*\""""
Number \d+ Number \d+
@@ -133,7 +133,7 @@ LabelConstant InternalLbl
} }
if (!item.AllowedTokenIds.Contains(next.Result.LexSegmentId)) 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; return operationResult;
} }
intermediateInstruction.Parameters.Add(next.Result); intermediateInstruction.Parameters.Add(next.Result);

View File

@@ -61,6 +61,10 @@ namespace SVM.Assembler.Core
} }
else else
{ {
if (TryParseUInt8(input, context, out registerID))
{
return true;
}
if (context.IntermediateObject.TryGetConst(input, out var realStr)) if (context.IntermediateObject.TryGetConst(input, out var realStr))
{ {
return TryParseRegister(realStr, context, out registerID); return TryParseRegister(realStr, context, out registerID);

View File

@@ -21,7 +21,7 @@ namespace SVM.Assembler.Core
if (DataOffsets.TryGetValue(label, out offset)) if (DataOffsets.TryGetValue(label, out offset))
{ {
//Don't directly give the length there. //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 true;
} }
return false; return false;
@@ -33,16 +33,18 @@ namespace SVM.Assembler.Core
{ {
return true; return true;
} }
int acc=0;
for (int i = 0; i < IntermediateObject.instructions.Count; i++) for (int i = 0; i < IntermediateObject.instructions.Count; i++)
{ {
IntermediateInstruction? item = IntermediateObject.instructions[i]; IntermediateInstruction? item = IntermediateObject.instructions[i];
if (item.Label != null) if (item.Label != null)
if (item.Label.Content == label) if (item.Label.Content == label)
{ {
this.label.Add(label, i); this.label.Add(label, acc);
offset = i; offset = acc;
return true; return true;
} }
acc += Definition.InstructionDefinitions[item.InstDefID].InstructionCount;
} }
return false; return false;
} }

View File

@@ -52,7 +52,7 @@
</InstructionParameter> </InstructionParameter>
</Parameters> </Parameters>
</InstructionDefinition> </InstructionDefinition>
<InstructionDefinition Id="std.int32" PrimaryInstruction="SD" InstructionCount="2"> <InstructionDefinition Id="sd.int32" PrimaryInstruction="SD" InstructionCount="2">
<Aliases> <Aliases>
<Alias Name="sd.int"/> <Alias Name="sd.int"/>
<Alias Name="sd.int32"/> <Alias Name="sd.int32"/>
@@ -112,7 +112,7 @@
</InstructionParameter> </InstructionParameter>
</Parameters> </Parameters>
</InstructionDefinition> </InstructionDefinition>
<InstructionDefinition Id="call" PrimaryInstruction="Call" InstructionCount="2"> <InstructionDefinition Id="call" PrimaryInstruction="Call" InstructionCount="1">
<Aliases> <Aliases>
<Alias Name="call"/> <Alias Name="call"/>
<Alias Name="c"/> <Alias Name="c"/>
@@ -122,8 +122,49 @@
<MatchingItems> <MatchingItems>
<Item Id="Number"/> <Item Id="Number"/>
<Item Id="Word"/> <Item Id="Word"/>
<Item Id="Register"/>
</MatchingItems> </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> </InstructionParameter>
</Parameters> </Parameters>
</InstructionDefinition> </InstructionDefinition>
@@ -133,13 +174,6 @@
<Alias Name="ret"/> <Alias Name="ret"/>
</Aliases> </Aliases>
<Parameters> <Parameters>
<InstructionParameter>
<MatchingItems>
<Item Id="Number"/>
<Item Id="Word"/>
</MatchingItems>
<ExpectedValue Type="Int32" Pos="4" Converter="Integer32" />
</InstructionParameter>
</Parameters> </Parameters>
</InstructionDefinition> </InstructionDefinition>
<InstructionDefinition Id="load" PrimaryInstruction="Load" InstructionCount="1"> <InstructionDefinition Id="load" PrimaryInstruction="Load" InstructionCount="1">
@@ -200,34 +234,5 @@
</InstructionParameter> </InstructionParameter>
</Parameters> </Parameters>
</InstructionDefinition> </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> </Definitions>
</ISARoot> </ISARoot>

View File

@@ -75,6 +75,10 @@ namespace SVM.Assembler
if (fResult.HasError()) if (fResult.HasError())
{ {
Console.Error.WriteLine("Finalizer error!"); Console.Error.WriteLine("Finalizer error!");
foreach (var item in fResult.Errors)
{
Console.Error.WriteLine(item.ToString());
}
return; return;
} }
if (fResult.Result == null) if (fResult.Result == null)

View File

@@ -26,12 +26,11 @@
SD, SD,
// 0 1 // 0 1
// JMP RD // JMP [R]TargetPC
// [I]Address (int32)
JMP, JMP,
// Jump And Link If Conditional Register is set. // Jump If Conditional Register is set.
// JIF RD FlagID // 0 1 2
// [I]Address (int32) // JIF [R]TargetPC [I]FlagID
JIF, JIF,
// 0 1 2 3 // 0 1 2 3
// Load [R]Address [I]Len [R]T // Load [R]Address [I]Len [R]T
@@ -39,9 +38,8 @@
// 0 1 2 3 // 0 1 2 3
// Load [R]Src [I]Len [R]TAddr // Load [R]Src [I]Len [R]TAddr
Save, Save,
// 0 // 0 1
// Call // Call [R]Address
// [I]Address (int64)
Call, Call,
// Return // Return
Return, Return,
@@ -77,7 +75,7 @@
Float, Float,
Double, Double,
} }
public enum ConditionFlag public enum ConditionFlag : byte
{ {
/// <summary> /// <summary>
/// Compare Flag /// Compare Flag

View File

@@ -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() public bool isReachBinaryEnd()
{ {
uint PCOffset = 1; uint PCOffset = 1;
@@ -214,12 +223,44 @@ namespace SVM.Core
var dataPtr = GetPointer(PC); var dataPtr = GetPointer(PC);
var data = dataPtr.GetData<int>(); var data = dataPtr.GetData<int>();
registers.SetDataInRegister(Reg, data); registers.SetDataInRegister(Reg, data);
//Console.WriteLine($"SVM:SD:{data} form PC={PC}"); Console.WriteLine($"SVM:SD:{data} to {Reg} form PC={PC}");
} }
break; break;
case PrimaryInstruction.JMP: case PrimaryInstruction.JMP:
{
var RegisterID = Instruction.GetData<byte>(1);
PC = registers.ReadData<ulong>(RegisterID);
Console.WriteLine($"Jump to:{PC}");
PC--;
}
break; break;
case PrimaryInstruction.JIF: 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; break;
case PrimaryInstruction.Load: case PrimaryInstruction.Load:
{ {
@@ -248,6 +289,10 @@ namespace SVM.Core
{ {
var cfPtr = GetPointer(ReadCallFrameRegisterAsPtr()); var cfPtr = GetPointer(ReadCallFrameRegisterAsPtr());
cfPtr.SetData(PC + 1); cfPtr.SetData(PC + 1);
var RegisterID = Instruction.GetData<byte>(1);
PC = registers.ReadData<ulong>(RegisterID);
Console.WriteLine($"Call to:{PC} ({RegisterID})");
PC--;
} }
break; break;
case PrimaryInstruction.Return: case PrimaryInstruction.Return:

View File

@@ -30,7 +30,16 @@ class Program
svm.Init(); svm.Init();
while (!svm.isReachBinaryEnd()) while (!svm.isReachBinaryEnd())
{ {
svm.Step(); try
{
svm.Step();
}
catch (Exception e)
{
Console.WriteLine($"Error at:{svm.GetPC()}");
Console.WriteLine(e);
throw;
}
} }
} }
} }

View File

@@ -13,6 +13,11 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SVM.Assembler", "SVM.Assemb
EndProject EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SVM.Advanced", "SVM.Advanced\SVM.Advanced.csproj", "{F9F2F699-49F7-4427-BA22-B444DD6259FD}" Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SVM.Advanced", "SVM.Advanced\SVM.Advanced.csproj", "{F9F2F699-49F7-4427-BA22-B444DD6259FD}"
EndProject 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 Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU Debug|Any CPU = Debug|Any CPU