コード例 #1
0
        public void NegativeStackOffset_IsUsedCalculateAddresses_InTheExistingStackFrame()
        {
            var offset   = new NewStackFrame(0, 3);
            var negative = new StackFrame(3);

            Assert.That(offset.NewStackPointer + negative.ReturnValue, Is.EqualTo(offset.ReturnValue));
            Assert.That(offset.NewStackPointer + negative.Register0, Is.EqualTo(offset.Register0));
            Assert.That(offset.NewStackPointer + negative.Register1, Is.EqualTo(offset.Register1));
            Assert.That(offset.NewStackPointer + negative.Register2, Is.EqualTo(offset.Register2));
            Assert.That(offset.NewStackPointer + negative.Register3, Is.EqualTo(offset.Register3));
            Assert.That(offset.NewStackPointer + negative.Register4, Is.EqualTo(offset.Register4));
            Assert.That(offset.NewStackPointer + negative.Register5, Is.EqualTo(offset.Register5));
            Assert.That(offset.NewStackPointer + negative.Register6, Is.EqualTo(offset.Register6));
        }
コード例 #2
0
        public void NewStackFrame_IsUsedToCalculateAddresses_InANewStackFrame_ForACaller()
        {
            // new stackframe beginning at address 20, with 3 arguments
            var offset = new NewStackFrame(20, 3);

            Assert.That(offset.ReturnValue, Is.EqualTo(20));
            Assert.That(offset.Argn(0), Is.EqualTo(21));
            Assert.That(offset.Argn(1), Is.EqualTo(22));
            Assert.That(offset.Argn(2), Is.EqualTo(23));
            Assert.That(() => offset.Argn(3), Throws.Exception.InstanceOf <ArgumentOutOfRangeException>());
            Assert.That(offset.ReturnAddress, Is.EqualTo(24));
            Assert.That(offset.Register0, Is.EqualTo(25));
            Assert.That(offset.Register1, Is.EqualTo(26));
            Assert.That(offset.Register2, Is.EqualTo(27));
            Assert.That(offset.Register3, Is.EqualTo(28));
            Assert.That(offset.Register4, Is.EqualTo(29));
            Assert.That(offset.Register5, Is.EqualTo(30));
            Assert.That(offset.Register6, Is.EqualTo(31));
            Assert.That(offset.NewStackPointer, Is.EqualTo(32));
        }
コード例 #3
0
        public static string Call(ref int lineNumber, NewStackFrame newStackFrame, StackFrame calleeStackFrame, string name)
        {
            return($@"* Call '{name}'
{lineNumber++}: ST 0, {newStackFrame.Register0}(6)   ; store registers in stack frame
{lineNumber++}: ST 1, {newStackFrame.Register1}(6)
{lineNumber++}: ST 2, {newStackFrame.Register2}(6)
{lineNumber++}: ST 3, {newStackFrame.Register3}(6)
{lineNumber++}: ST 4, {newStackFrame.Register4}(6)
{lineNumber++}: ST 5, {newStackFrame.Register5}(6)
{lineNumber++}: ST 6, {newStackFrame.Register6}(6)
{lineNumber++}: LDA 5, 3(7)  ; calculate address of **return point** 
{lineNumber++}: ST 5, {newStackFrame.ReturnAddress}(6)   ; store return address in stack frame
{lineNumber++}: LDA 6, {newStackFrame.NewStackPointer}(6)  ; set value of stack pointer (r6) to one past top of new stack frame
{lineNumber++}: LDA 7, [func:{name}](0)  ; jump to function
{lineNumber++}: LD 0, {calleeStackFrame.Register0}(6)  ; **return point**,  restore registers from stack frame
{lineNumber++}: LD 1, {calleeStackFrame.Register1}(6)
{lineNumber++}: LD 2, {calleeStackFrame.Register2}(6)
{lineNumber++}: LD 3, {calleeStackFrame.Register3}(6)
{lineNumber++}: LD 4, {calleeStackFrame.Register4}(6)
{lineNumber++}: LD 5, {calleeStackFrame.Register5}(6)
{lineNumber++}: LD 6, {calleeStackFrame.Register6}(6)  ; r6 stack pointer gets loaded last
* End Call '{name}'
");
        }
コード例 #4
0
        public static string Param(ref int lineNumber, StackFrame stackFrame, NewStackFrame newStackFrame, string variable, int argNum)
        {
            return($@"{lineNumber++}: LD 2, {stackFrame.Address(variable)}(6) ; param{argNum} := {variable}
{lineNumber++}: ST 2, {newStackFrame.Argn(argNum)}(6)
");
        }