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"
.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

View File

@@ -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();
}

View File

@@ -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);

View File

@@ -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);

View File

@@ -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;
}

View File

@@ -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>

View File

@@ -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)

View File

@@ -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

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()
{
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:

View File

@@ -30,7 +30,16 @@ class Program
svm.Init();
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
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