Presentation is loading. Please wait.

Presentation is loading. Please wait.

Principles of Computers 18th Lecture

Similar presentations


Presentation on theme: "Principles of Computers 18th Lecture"— Presentation transcript:

1 Principles of Computers 18th Lecture
Pavel Ježek, Ph.D.

2

3 6502 Registers (Accumulator Architecture)
X Y S P PC 6502: 8-bit CPU with 16-bit logical and physical address spaces (1:1 mapping between logical and physical addresses, i.e. logical address = physical address)

4 Load and Store & Setting Flags
LDA #$xx LDA $xxxx LDA $xxxx,X LDA $xxxx,Y LDX imm/addr LDY imm/addr STA $xxxx STA $xxxx,X STA $xxxx,Y STX addr STY addr A := xx A := ($xxxx)^ A := ($xxxx + X)^ A := ($xxxx + Y)^ X := imm/addr Y := imm/addr ($xxxx)^ := A ($xxxx + X)^ := A ($xxxx + Y)^ := A addr := X addr := Y TAX TXA TAY TYA TSX TXS X := A A := X Y := A A := Y X := S S := X P N... ..Z. P.Negative := target.7 if target = 0 then P.Zero := 1 else P.Zero := 0; PHP PLP PHA PLA push P (flags) pop P (flags) push A pop A CLC SEC P.Carry := 0 P.Carry := 1

5 Bitwise Operations ORA imm/addr AND imm/addr EOR imm/addr ? NOT ASL A
LSR A ROL A ROR A A := A BitwiseOr imm/addr A := A BitwiseAnd imm/addr A := A BitwiseXor imm/addr EOR #$FF A := A shl 1 A := A shr 1 A := A rol 1 A := A ror 1 P.Negative := A.7 if A = 0 then P.Zero := 1 else P.Zero := 0;

6 Integer Operations (Adding 8-bit Numbers)
ADC imm/addr result := A + imm/addr + P.Carry P.Carry := result.8 A := result.7 … result.0 P N... ..ZC P.Negative := A.7 if A = 0 then P.Zero := 1 else P.Zero := 0; LSB of A stored at $A000 A7 A6 A5 A4 A3 A2 A1 A0 carry + + LSB of B stored at $B000 B7 B6 B5 B4 B3 B2 B1 B0 = LSB of C stored at $C000 = C8 carry C7 C6 C5 C4 C3 C2 C1 C0 LDA $A000 CLC ADC $B000 STA $C000

7 Integer Operations – Subtraction? Subtract with Borrow
ADC imm/addr SBC imm/addr result := A + imm/addr + P.Carry P.Carry := result.8 A := result.7 … result.0 result := A – imm/addr – not(P.Carry) P.Carry := not(result.7) P.Negative := A.7 if A = 0 then P.Zero := 1 else P.Zero := 0; P.Negative := A.7 if A = 0 then P.Zero := 1 else P.Zero := 0; P.Negative := X/Y.7 if X/Y = 0 then P.Zero := 1 else P.Zero := 0; INX INY DEX DEY X := X + 1 Y := Y + 1 X := X – 1 Y := Y - 1

8 No Division (div), No Mutiplication (*) Instructions on 6502

9

10 How To Write/Compile Complex Expressions?
x := 1 + a + F1(b + c) * F2(d + e + F3(2, 3), f + F4(4)) + F5(5) + x;

11 Rewriting Complex Expressions – Step 1: Function Calls As Separate Commands, Each Having Variables and Constants As Arguments Only (i.e. No Expressions As Arguments) x := 1 + a + F1(b + c) * F2(d + e + F3(2, 3), f + F4(4)) + F5(5) + x; temp11 := b + c; temp12 := F1(temp11); temp21 := F3(2, 3); temp22 := d + e + temp21; temp23 := F4(4); temp24 := f + temp23; temp25 := F2(temp22, temp24); temp31 := F5(5); x := 1 + a + temp12 * temp25 + temp31 + x; Introducing temporary variables to hold intermediate results of inner subexpressions

12 Step 2: Rewrite To Have a := b op c Or d := F(…) Only
x := 1 + a + F1(b + c) * F2(d + e + F3(2, 3), f + F4(4)) + F5(5) + x; temp11 := b + c; temp12 := F1(temp11); temp21 := F3(2, 3); temp22 := d + e; temp22 := temp22 + temp21; temp23 := F4(4); temp24 := f + temp23; temp25 := F2(temp22, temp24); temp31 := F5(5); tempX := 1 + a; temp4 := temp12 * temp25; tempX := tempX + temp4; tempX := tempX + temp31; x := tempX + x; temp11 := b + c; temp12 := F1(temp11); temp21 := F3(2, 3); temp22 := d + e + temp21; temp23 := F4(4); temp24 := f + temp23; temp25 := F2(temp22, temp24); temp31 := F5(5); x := 1 + a + temp12 * temp25 + temp31 + x;

13 Step 3 (If Target CPU Does Not Support a := b op c): a := a + b
x := 1 + a + F1(b + c) * F2(d + e + F3(2, 3), f + F4(4)) + F5(5) + x; temp11 := b; temp11 := temp11 + c; temp12 := F1(temp11); temp21 := F3(2, 3); temp22 := d; temp22 := temp22 + e; temp22 := temp22 + temp21; temp23 := F4(4); temp24 := f; temp24 := temp24 + temp23; temp25 := F2(temp22, temp24); temp31 := F5(5); tempX := 1 { x := 1 + a + temp12 * temp25 + temp31 + x; } tempX := tempX + a; temp4 := temp12; temp4 := temp4 * temp25; tempX := tempX + temp4; tempX := tempX + temp31; tempX := tempX + x; x := tempX; OR x := x + tempX; temp11 := b + c; temp12 := F1(temp11); temp21 := F3(2, 3); temp22 := d + e; temp22 := temp22 + temp21; temp23 := F4(4); temp24 := f + temp23; temp25 := F2(temp22, temp24); temp31 := F5(5); tempX := 1 + a; temp4 := temp12 * temp25; tempX := tempX + temp4; tempX := tempX + temp31; x := tempX + x;

14 Step 4: Rewriting Function Calls – Expecting Calling Convention With Arguments Passed On Stack
x := 1 + a + F1(b + c) * F2(d + e + F3(2, 3), f + F4(4)) + F5(5) + x; temp11 := b; temp11 := temp11 + c; push temp11 call F1 temp12 := returnValue; push 3 push 2 call F3 temp21 := returnValue; temp22 := d; temp22 := temp22 + e; temp22 := temp22 + temp21; push 4 call F4 temp23 := returnValue; temp24 := f; temp24 := temp24 + temp23; push temp24 push temp22 call F2 temp25 := returnValue; push 5 call F5 temp31 := returnValue; tempX := 1 tempX := tempX + a; temp4 := temp12; temp4 := temp4 * temp25; tempX := tempX + temp4; tempX := tempX + temp31; tempX := tempX + x; x := tempX;

15 Step 5: Rewrite Operations Unsupported by Target CPU into Calls to Runtime
x := 1 + a + F1(b + c) * F2(d + e + F3(2, 3), f + F4(4)) + F5(5) + x; temp11 := b; temp11 := temp11 + c; push temp11 call F1 temp12 := returnValue; push 3 push 2 call F3 temp21 := returnValue; temp22 := d; temp22 := temp22 + e; temp22 := temp22 + temp21; push 4 call F4 temp23 := returnValue; temp24 := f; temp24 := temp24 + temp23; push temp24 push temp22 call F2 temp25 := returnValue; push 5 call F5 temp31 := returnValue; tempX := 1 tempX := tempX + a; push temp12 temp4 := temp12; push temp25 temp4 := temp4 * temp25; call runtimeMultiply temp4 := returnValue tempX := tempX + temp4; tempX := tempX + temp31; tempX := tempX + x; x := tempX;

16 Target CPU: 6502 x := 1 + a + F1(b + c) * F2(d + e + F3(2, 3), f + F4(4)) + F5(5) + x; temp11 := b; temp11 := temp11 + c; push temp11 call F1 temp12 := returnValue; push 3 push 2 call F3 temp21 := returnValue; temp22 := d; temp22 := temp22 + e; temp22 := temp22 + temp21; push 4 call F4 temp23 := returnValue; temp24 := f; temp24 := temp24 + temp23; push temp24 push temp22 call F2 temp25 := returnValue; push 5 call F5 temp31 := returnValue; tempX := 1 tempX := tempX + a; temp4 := temp12; temp4 := temp4 * temp25; call Pascal runtime temp4 := returnValue tempX := tempX + temp4; tempX := tempX + temp31; tempX := tempX + x; x := tempX;

17 Target CPU: 6502 x := 1 + a + F1(b + c) * F2(d + e + F3(2, 3), f + F4(4)) + F5(5) + x; temp11 := b; temp11 := temp11 + c; push temp11 call F1 temp12 := returnValue; LDA # push 3 PHA LDA # push 2 JSR &F call F3 temp21 := returnValue; temp22 := d; temp22 := temp22 + e; temp22 := temp22 + temp21; push 4 call F4 temp23 := returnValue; temp24 := f; temp24 := temp24 + temp23; push temp24 push temp22 call F2 temp25 := returnValue; push 5 call F5 temp31 := returnValue; tempX := 1 tempX := tempX + a; temp4 := temp12; temp4 := temp4 * temp25; call Pascal runtime temp4 := returnValue tempX := tempX + temp4; tempX := tempX + temp31; tempX := tempX + x; x := tempX;

18 Passing all return values in A register
Target CPU: 6502 x := 1 + a + F1(b + c) * F2(d + e + F3(2, 3), f + F4(4)) + F5(5) + x; Passing all return values in A register temp11 := b; temp11 := temp11 + c; push temp11 call F1 temp12 := returnValue; LDA # push 3 PHA LDA # push 2 JSR &F call F3 temp21 := returnValue; temp22 := d; temp22 := temp22 + e; temp22 := temp22 + temp21; push 4 call F4 temp23 := returnValue; temp24 := f; temp24 := temp24 + temp23; push temp24 push temp22 call F2 temp25 := returnValue; push 5 call F5 temp31 := returnValue; tempX := 1 tempX := tempX + a; temp4 := temp12; temp4 := temp4 * temp25; call Pascal runtime temp4 := returnValue tempX := tempX + temp4; tempX := tempX + temp31; tempX := tempX + x; x := tempX;

19 Passing all return values in A register
Target CPU: 6502 x := 1 + a + F1(b + c) * F2(d + e + F3(2, 3), f + F4(4)) + F5(5) + x; Passing all return values in A register temp11 := b; temp11 := temp11 + c; push temp11 call F1 temp12 := returnValue; LDA # push 3 PHA LDA # push 2 JSR &F call F3 STA &temp temp21 := returnValue; temp22 := d; temp22 := temp22 + e; temp22 := temp22 + temp21; push 4 call F4 temp23 := returnValue; temp24 := f; temp24 := temp24 + temp23; push temp24 push temp22 call F2 temp25 := returnValue; push 5 call F5 temp31 := returnValue; tempX := 1 tempX := tempX + a; temp4 := temp12; temp4 := temp4 * temp25; call Pascal runtime temp4 := returnValue tempX := tempX + temp4; tempX := tempX + temp31; tempX := tempX + x; x := tempX;

20 Passing all return values in A register
Target CPU: 6502 x := 1 + a + F1(b + c) * F2(d + e + F3(2, 3), f + F4(4)) + F5(5) + x; Passing all return values in A register temp11 := b; temp11 := temp11 + c; push temp11 call F1 temp12 := returnValue; LDA # push 3 PHA LDA # push 2 JSR &F call F3 STA &temp temp21 := returnValue; temp22 := d; temp22 := temp22 + e; temp22 := temp22 + temp21; LDA # push 4 JSR &F call F4 STA &temp temp23 := returnValue; temp24 := f; temp24 := temp24 + temp23; push temp24 push temp22 call F2 temp25 := returnValue; LDA # push 5 PHA JSR &F5 call F5 STA &temp31 temp31 := returnValue; tempX := 1 tempX := tempX + a; temp4 := temp12; temp4 := temp4 * temp25; call Pascal runtime temp4 := returnValue tempX := tempX + temp4; tempX := tempX + temp31; tempX := tempX + x; x := tempX;

21 x := 1 + a + F1(b + c) * F2(d + e + F3(2, 3), f + F4(4)) + F5(5) + x;
Target CPU: 6502 x := 1 + a + F1(b + c) * F2(d + e + F3(2, 3), f + F4(4)) + F5(5) + x; Passing all return values in A register temp11 := b; temp11 := temp11 + c; push temp11 call F1 temp12 := returnValue; LDA # push 3 PHA LDA # push 2 JSR &F call F3 STA &temp temp21 := returnValue; temp22 := d; temp22 := temp22 + e; temp22 := temp22 + temp21; LDA # push 4 JSR &F call F4 STA &temp temp23 := returnValue; temp24 := f; temp24 := temp24 + temp23; push temp24 push temp22 call F2 temp25 := returnValue; LDA # push 5 PHA JSR &F5 call F5 STA &temp31 temp31 := returnValue; tempX := 1 tempX := tempX + a; temp4 := temp12; temp4 := temp4 * temp25; JSR &runtimeMultiply call Pascal runtime STA &temp4 temp4 := returnValue tempX := tempX + temp4; tempX := tempX + temp31; tempX := tempX + x; x := tempX; Arguments of the runtimeMultiply function call

22 x := 1 + a + F1(b + c) * F2(d + e + F3(2, 3), f + F4(4)) + F5(5) + x;
Target CPU: 6502 x := 1 + a + F1(b + c) * F2(d + e + F3(2, 3), f + F4(4)) + F5(5) + x; Passing all return values in A register temp11 := b; temp11 := temp11 + c; push temp11 call F1 temp12 := returnValue; LDA # push 3 PHA LDA # push 2 JSR &F call F3 STA &temp temp21 := returnValue; temp22 := d; temp22 := temp22 + e; temp22 := temp22 + temp21; LDA # push 4 JSR &F call F4 STA &temp temp23 := returnValue; temp24 := f; temp24 := temp24 + temp23; push temp24 push temp22 call F2 temp25 := returnValue; LDA # push 5 PHA JSR &F5 call F5 STA &temp31 temp31 := returnValue; tempX := 1 tempX := tempX + a; LDA &temp12 temp4 := temp12; LDA &temp25 temp4 := temp4 * temp25; JSR &runtimeMultiply call Pascal runtime STA &temp4 temp4 := returnValue tempX := tempX + temp4; tempX := tempX + temp31; tempX := tempX + x; x := tempX; Arguments of the runtimeMultiply function call

23 Passing all return values in A register
Target CPU: 6502 x := 1 + a + F1(b + c) * F2(d + e + F3(2, 3), f + F4(4)) + F5(5) + x; Passing all return values in A register temp11 := b; temp11 := temp11 + c; push temp11 call F1 temp12 := returnValue; LDA # push 3 PHA LDA # push 2 JSR &F call F3 STA &temp temp21 := returnValue; LDA &d temp22 := d; ADC &e temp22 := temp22 + e; ADC &temp temp22 := temp22 + temp21; STA &temp22 LDA # push 4 JSR &F call F4 STA &temp temp23 := returnValue; temp24 := f; temp24 := temp24 + temp23; push temp24 push temp22 call F2 temp25 := returnValue; LDA # push 5 PHA JSR &F5 call F5 STA &temp31 temp31 := returnValue; tempX := 1 tempX := tempX + a; LDA &temp12 temp4 := temp12; LDA &temp25 temp4 := temp4 * temp25; JSR &runtimeMultiply call Pascal runtime STA &temp4 temp4 := returnValue tempX := tempX + temp4; tempX := tempX + temp31; tempX := tempX + x; x := tempX; If temp* is part of arithmetic operation, it needs to be loaded into A

24 Passing all return values in A register
Target CPU: 6502 x := 1 + a + F1(b + c) * F2(d + e + F3(2, 3), f + F4(4)) + F5(5) + x; Passing all return values in A register LDA &b temp11 := b; ADC &c temp11 := temp11 + c; PHA push temp11 JSR &F1 call F1 STA &temp12 temp12 := returnValue; LDA # push 3 PHA LDA # push 2 JSR &F call F3 STA &temp temp21 := returnValue; LDA &d temp22 := d; ADC &e temp22 := temp22 + e; ADC &temp temp22 := temp22 + temp21; STA &temp22 LDA # push 4 JSR &F call F4 STA &temp temp23 := returnValue; temp24 := f; temp24 := temp24 + temp23; push temp24 push temp22 call F2 temp25 := returnValue; LDA # push 5 PHA JSR &F5 call F5 STA &temp31 temp31 := returnValue; tempX := 1 tempX := tempX + a; LDA &temp12 temp4 := temp12; LDA &temp25 temp4 := temp4 * temp25; JSR &runtimeMultiply call Pascal runtime STA &temp4 temp4 := returnValue tempX := tempX + temp4; tempX := tempX + temp31; tempX := tempX + x; x := tempX; If temp* is part of arithmetic operation, it needs to be loaded into A

25 Passing all return values in A register
Target CPU: 6502 x := 1 + a + F1(b + c) * F2(d + e + F3(2, 3), f + F4(4)) + F5(5) + x; Passing all return values in A register LDA &b temp11 := b; ADC &c temp11 := temp11 + c; PHA push temp11 JSR &F1 call F1 STA &temp12 temp12 := returnValue; LDA # push 3 PHA LDA # push 2 JSR &F call F3 STA &temp temp21 := returnValue; LDA &d temp22 := d; ADC &e temp22 := temp22 + e; ADC &temp temp22 := temp22 + temp21; STA &temp22 LDA # push 4 JSR &F call F4 STA &temp temp23 := returnValue; LDA &f temp24 := f; ADC &temp temp24 := temp24 + temp23; PHA push temp24 LDA &temp22 push temp22 JSR &f2 call F2 STA &temp25 temp25 := returnValue; LDA # push 5 PHA JSR &F5 call F5 STA &temp31 temp31 := returnValue; tempX := 1 tempX := tempX + a; LDA &temp12 temp4 := temp12; LDA &temp25 temp4 := temp4 * temp25; JSR &runtimeMultiply call Pascal runtime STA &temp4 temp4 := returnValue tempX := tempX + temp4; tempX := tempX + temp31; tempX := tempX + x; x := tempX;

26 Passing all return values in A register
Target CPU: 6502 x := 1 + a + F1(b + c) * F2(d + e + F3(2, 3), f + F4(4)) + F5(5) + x; Passing all return values in A register LDA &b temp11 := b; ADC &c temp11 := temp11 + c; PHA push temp11 JSR &F1 call F1 STA &temp12 temp12 := returnValue; LDA # push 3 PHA LDA # push 2 JSR &F call F3 STA &temp temp21 := returnValue; LDA &d temp22 := d; ADC &e temp22 := temp22 + e; ADC &temp temp22 := temp22 + temp21; STA &temp22 LDA # push 4 JSR &F call F4 STA &temp temp23 := returnValue; LDA &f temp24 := f; ADC &temp temp24 := temp24 + temp23; PHA push temp24 LDA &temp22 push temp22 JSR &f2 call F2 STA &temp25 temp25 := returnValue; LDA # push 5 PHA JSR &F5 call F5 STA &temp31 temp31 := returnValue; tempX := 1 tempX := tempX + a; LDA &temp12 temp4 := temp12; LDA &temp25 temp4 := temp4 * temp25; JSR &runtimeMultiply call Pascal runtime STA &temp4 temp4 := returnValue tempX := tempX + temp4; tempX := tempX + temp31; tempX := tempX + x; x := tempX; x := 1 + a + temp12 * temp25 + temp31 + x;

27 Passing all return values in A register
Target CPU: 6502 x := 1 + a + F1(b + c) * F2(d + e + F3(2, 3), f + F4(4)) + F5(5) + x; Passing all return values in A register LDA &b temp11 := b; ADC &c temp11 := temp11 + c; PHA push temp11 JSR &F1 call F1 STA &temp12 temp12 := returnValue; LDA # push 3 PHA LDA # push 2 JSR &F call F3 STA &temp temp21 := returnValue; LDA &d temp22 := d; ADC &e temp22 := temp22 + e; ADC &temp temp22 := temp22 + temp21; STA &temp22 LDA # push 4 JSR &F call F4 STA &temp temp23 := returnValue; LDA &f temp24 := f; ADC &temp temp24 := temp24 + temp23; PHA push temp24 LDA &temp22 push temp22 JSR &f2 call F2 STA &temp25 temp25 := returnValue; LDA # push 5 PHA JSR &F5 call F5 STA &temp31 temp31 := returnValue; LDA #1 tempX := 1 ADC &a tempX := tempX + a; LDA &temp12 temp4 := temp12; LDA &temp25 temp4 := temp4 * temp25; JSR &runtimeMultiply call Pascal runtime STA &temp4 temp4 := returnValue ADC &temp4 tempX := tempX + temp4; ADC &temp31 tempX := tempX + temp31; ADC &x tempX := tempX + x; STA &x x := tempX; x := 1 + a + temp12 * temp25 + temp31 + x;

28 x := 1 + a + F1(b + c) * F2(d + e + F3(2, 3), f + F4(4)) + F5(5) + x;
Target CPU: 6502 x := 1 + a + F1(b + c) * F2(d + e + F3(2, 3), f + F4(4)) + F5(5) + x; Passing all return values in A register LDA &b temp11 := b; ADC &c temp11 := temp11 + c; PHA push temp11 JSR &F1 call F1 STA &temp12 temp12 := returnValue; LDA # push 3 PHA LDA # push 2 JSR &F call F3 STA &temp temp21 := returnValue; LDA &d temp22 := d; ADC &e temp22 := temp22 + e; ADC &temp temp22 := temp22 + temp21; STA &temp22 LDA # push 4 JSR &F call F4 STA &temp temp23 := returnValue; LDA &f temp24 := f; ADC &temp temp24 := temp24 + temp23; PHA push temp24 LDA &temp22 push temp22 JSR &f2 call F2 STA &temp25 temp25 := returnValue; LDA # push 5 PHA JSR &F5 call F5 STA &temp31 temp31 := returnValue; LDA #1 tempX := 1 ADC &a tempX := tempX + a; LDA &temp12 temp4 := temp12; LDA &temp25 temp4 := temp4 * temp25; JSR &runtimeMultiply call Pascal runtime STA &temp4 temp4 := returnValue ADC &temp4 tempX := tempX + temp4; ADC &temp31 tempX := tempX + temp31; ADC &x tempX := tempX + x; STA &x x := tempX; x := 1 + a + temp12 * temp25 + temp31 + x; A ≠ tempX but was overwritten by current value of temp12, then temp25, then temp4

29 Passing all return values in A register
Target CPU: 6502 x := 1 + a + F1(b + c) * F2(d + e + F3(2, 3), f + F4(4)) + F5(5) + x; Passing all return values in A register LDA &b temp11 := b; ADC &c temp11 := temp11 + c; PHA push temp11 JSR &F1 call F1 STA &temp12 temp12 := returnValue; LDA # push 3 PHA LDA # push 2 JSR &F call F3 STA &temp temp21 := returnValue; LDA &d temp22 := d; ADC &e temp22 := temp22 + e; ADC &temp temp22 := temp22 + temp21; STA &temp22 LDA # push 4 JSR &F call F4 STA &temp temp23 := returnValue; LDA &f temp24 := f; ADC &temp temp24 := temp24 + temp23; PHA push temp24 LDA &temp22 push temp22 JSR &f2 call F2 STA &temp25 temp25 := returnValue; LDA # push 5 PHA JSR &F5 call F5 STA &temp31 temp31 := returnValue; LDA #1 tempX := 1 ADC &a tempX := tempX + a; TAY save tempX into Y reg. LDA &temp12 temp4 := temp12; LDA &temp25 temp4 := temp4 * temp25; JSR &runtimeMultiply call Pascal runtime STA &temp4 temp4 := returnValue TYA restore tempX from Y ADC &temp4 tempX := tempX + temp4; ADC &temp31 tempX := tempX + temp31; ADC &x tempX := tempX + x; STA &x x := tempX; x := 1 + a + temp12 * temp25 + temp31 + x;

30 LDA &b temp11 := b; CLC ADC &c temp11 := temp11 + c; PHA push temp11 JSR &F1 call F1 STA &temp12 temp12 := returnValue; LDA # push 3 PHA LDA # push 2 JSR &F call F3 STA &temp temp21 := returnValue; LDA &d temp22 := d; ADC &e temp22 := temp22 + e; ADC &temp temp22 := temp22 + temp21; STA &temp22 LDA # push 4 JSR &F call F4 STA &temp temp23 := returnValue; LDA &f temp24 := f; ADC &temp temp24 := temp24 + temp23; PHA push temp24 LDA &temp22 push temp22 JSR &f2 call F2 STA &temp25 temp25 := returnValue; Fix 8-bit Additions x := 1 + a + F1(b + c) * F2(d + e + F3(2, 3), f + F4(4)) + F5(5) + x; LDA # push 5 PHA JSR &F5 call F5 STA &temp31 temp31 := returnValue; LDA #1 tempX := 1 CLC ADC &a tempX := tempX + a; TAY save tempX into Y reg. LDA &temp12 temp4 := temp12; LDA &temp25 temp4 := temp4 * temp25; JSR &runtimeMultiply call Pascal runtime STA &temp4 temp4 := returnValue TYA restore tempX from Y ADC &temp4 tempX := tempX + temp4; ADC &temp31 tempX := tempX + temp31; ADC &x tempX := tempX + x; STA &x x := tempX;

31 Allocate space for 7 temporary variables on stack
LDA &b temp11 := b; CLC ADC &c temp11 := temp11 + c; PHA push temp11 JSR &F1 call F1 STA &temp12 temp12 := returnValue; LDA # push 3 PHA LDA # push 2 JSR &F call F3 STA &temp temp21 := returnValue; LDA &d temp22 := d; ADC &e temp22 := temp22 + e; ADC &temp temp22 := temp22 + temp21; STA &temp22 LDA # push 4 JSR &F call F4 STA &temp temp23 := returnValue; LDA &f temp24 := f; ADC &temp temp24 := temp24 + temp23; PHA push temp24 LDA &temp22 push temp22 JSR &f2 call F2 STA &temp25 temp25 := returnValue; Allocate space for 7 temporary variables on stack x := 1 + a + F1(b + c) * F2(d + e + F3(2, 3), f + F4(4)) + F5(5) + x; LDA # push 5 PHA JSR &F5 call F5 STA &temp31 temp31 := returnValue; LDA #1 tempX := 1 CLC ADC &a tempX := tempX + a; TAY save tempX into Y reg. LDA &temp12 temp4 := temp12; LDA &temp25 temp4 := temp4 * temp25; JSR &runtimeMultiply call Pascal runtime STA &temp4 temp4 := returnValue TYA restore tempX from Y ADC &temp4 tempX := tempX + temp4; ADC &temp31 tempX := tempX + temp31; ADC &x tempX := tempX + x; STA &x x := tempX; 6 1 2 7 3 4 5

32 Allocate space for 7 temporary variables on stack
S := S - 7 LDA &b temp11 := b; CLC ADC &c temp11 := temp11 + c; PHA push temp11 JSR &F1 call F1 STA &temp12 temp12 := returnValue; LDA # push 3 PHA LDA # push 2 JSR &F call F3 STA &temp temp21 := returnValue; LDA &d temp22 := d; ADC &e temp22 := temp22 + e; ADC &temp temp22 := temp22 + temp21; STA &temp22 LDA # push 4 JSR &F call F4 STA &temp temp23 := returnValue; LDA &f temp24 := f; ADC &temp temp24 := temp24 + temp23; PHA push temp24 LDA &temp22 push temp22 JSR &f2 call F2 STA &temp25 temp25 := returnValue; Allocate space for 7 temporary variables on stack x := 1 + a + F1(b + c) * F2(d + e + F3(2, 3), f + F4(4)) + F5(5) + x; LDA # push 5 PHA JSR &F5 call F5 STA &temp31 temp31 := returnValue; LDA #1 tempX := 1 CLC ADC &a tempX := tempX + a; TAY save tempX into Y reg. LDA &temp12 temp4 := temp12; LDA &temp25 temp4 := temp4 * temp25; JSR &runtimeMultiply call Pascal runtime STA &temp4 temp4 := returnValue TYA restore tempX from Y ADC &temp4 tempX := tempX + temp4; ADC &temp31 tempX := tempX + temp31; ADC &x tempX := tempX + x; STA &x x := tempX; S := S + 7 6 1 2 7 3 4 5

33 Allocate space for 7 temporary variables on stack
TSX allocate 7 one byte temps TXA SEC SBC #7 TAX TXS LDA &b temp11 := b; CLC ADC &c temp11 := temp11 + c; PHA push temp11 JSR &F1 call F1 STA &temp12 temp12 := returnValue; LDA # push 3 PHA LDA # push 2 JSR &F call F3 STA &temp temp21 := returnValue; LDA &d temp22 := d; ADC &e temp22 := temp22 + e; ADC &temp temp22 := temp22 + temp21; STA &temp22 LDA # push 4 JSR &F call F4 STA &temp temp23 := returnValue; LDA &f temp24 := f; ADC &temp temp24 := temp24 + temp23; PHA push temp24 LDA &temp22 push temp22 JSR &f2 call F2 STA &temp25 temp25 := returnValue; Allocate space for 7 temporary variables on stack x := 1 + a + F1(b + c) * F2(d + e + F3(2, 3), f + F4(4)) + F5(5) + x; LDA # push 5 PHA JSR &F5 call F5 STA &temp31 temp31 := returnValue; LDA #1 tempX := 1 CLC ADC &a tempX := tempX + a; TAY save tempX into Y reg. LDA &temp12 temp4 := temp12; LDA &temp25 temp4 := temp4 * temp25; JSR &runtimeMultiply call Pascal runtime STA &temp4 temp4 := returnValue TYA restore tempX from Y ADC &temp4 tempX := tempX + temp4; ADC &temp31 tempX := tempX + temp31; ADC &x tempX := tempX + x; STA &x x := tempX; TSX free 7 one byte temps TXA ADC #7 TAX TXS

34 Removing arguments from stack Passing all return values in A register
TSX allocate 7 one byte temps TXA SEC SBC #7 TAX TXS LDA &b temp11 := b; CLC ADC &c temp11 := temp11 + c; PHA push temp11 JSR &F1 call F1 TSX remove arguments from stack INX STA &temp12 temp12 := returnValue; LDA #3 push 3 PHA LDA #2 push 2 JSR &F3 call F3 TSX remove arguments from stack STA &temp21 temp21 := returnValue; LDA &d temp22 := d; ADC &e temp22 := temp22 + e; ADC &temp temp22 := temp22 + temp21; STA &temp22 LDA # push 4 JSR &F call F4 TSX remove arguments from stack STA &temp temp23 := returnValue; LDA &f temp24 := f; ADC &temp temp24 := temp24 + temp23; PHA push temp24 LDA &temp22 push temp22 JSR &f2 call F2 STA &temp25 temp25 := returnValue; x := 1 + a + F1(b + c) * F2(d + e + F3(2, 3), f + F4(4)) + F5(5) + x; LDA #5 push 5 PHA JSR &F5 call F5 TSX remove arguments from stack INX TXS STA &temp31 temp31 := returnValue; LDA #1 tempX := 1 CLC ADC &a tempX := tempX + a; TAY save tempX into Y reg. LDA &temp12 temp4 := temp12; LDA &temp25 temp4 := temp4 * temp25; JSR &runtimeMultiply call Pascal runtime STA &temp temp4 := returnValue TSX remove arguments from stack TYA restore tempX from Y ADC &temp4 tempX := tempX + temp4; ADC &temp31 tempX := tempX + temp31; ADC &x tempX := tempX + x; STA &x x := tempX; TSX free 7 one byte temps TXA ADC #7 TAX

35 x := 1 + a + F1(b + c) * F2(d + e + F3(2, 3), f + F4(4)) + F5(5) + x;
TSX allocate 7 one byte temps TXA SEC SBC #7 TAX TXS LDA &b temp11 := b; CLC ADC &c temp11 := temp11 + c; PHA push temp11 JSR &F1 call F1 TSX INX remove arguments from stack STA &temp12 temp12 := returnValue; LDA #3 push 3 PHA LDA #2 push 2 JSR &F3 call F3 TSX remove arguments from stack INX STA &temp21 temp21 := returnValue; LDA &d temp22 := d; ADC &e temp22 := temp22 + e; ADC &temp temp22 := temp22 + temp21; STA &temp22 LDA # push 4 JSR &F call F4 TSX remove arguments from stack STA &temp temp23 := returnValue; LDA &f temp24 := f; ADC &temp temp24 := temp24 + temp23; PHA push temp24 LDA &temp22 push temp22 JSR &f2 call F2 TSX remove arguments from stack STA &temp25 temp25 := returnValue; Passing return value on stack for F1, and in accumulator for F2, F3, F4, F5 x := 1 + a + F1(b + c) * F2(d + e + F3(2, 3), f + F4(4)) + F5(5) + x; LDA #5 push 5 PHA JSR &F5 call F5 TSX remove arguments from stack INX TXS STA &temp31 temp31 := returnValue; LDA #1 tempX := 1 CLC ADC &a tempX := tempX + a; TAY save tempX into Y reg. LDA &temp12 temp4 := temp12; LDA &temp25 temp4 := temp4 * temp25; JSR &runtimeMultiply call Pascal runtime STA &temp temp4 := returnValue TSX remove arguments from stack TYA restore tempX from Y ADC &temp4 tempX := tempX + temp4; ADC &temp31 tempX := tempX + temp31; ADC &x tempX := tempX + x; STA &x x := tempX; TSX free 7 one byte temps TXA ADC #7 TAX

36 x := 1 + a + F1(b + c) * F2(d + e + F3(2, 3), f + F4(4)) + F5(5) + x;
TSX allocate 7 one byte temps TXA SEC SBC #7 TAX TXS LDA &b temp11 := b; CLC ADC &c temp11 := temp11 + c; PHA push temp11 PHA reserve space for return value by pushing dummy value JSR &F1 call F1 TSX ?? save return value into A INX remove return value from stack INX remove arguments from stack STA &temp12 temp12 := returnValue; LDA #3 push 3 PHA LDA #2 push 2 JSR &F3 call F3 TSX remove arguments from stack INX STA &temp21 temp21 := returnValue; LDA &d temp22 := d; ADC &e temp22 := temp22 + e; ADC &temp temp22 := temp22 + temp21; STA &temp22 LDA # push 4 JSR &F call F4 TSX remove arguments from stack STA &temp temp23 := returnValue; LDA &f temp24 := f; ADC &temp temp24 := temp24 + temp23; PHA push temp24 LDA &temp22 push temp22 JSR &f2 call F2 TSX remove arguments from stack STA &temp25 temp25 := returnValue; Passing return value on stack for F1, and in accumulator for F2, F3, F4, F5 x := 1 + a + F1(b + c) * F2(d + e + F3(2, 3), f + F4(4)) + F5(5) + x; LDA #5 push 5 PHA JSR &F5 call F5 TSX remove arguments from stack INX TXS STA &temp31 temp31 := returnValue; LDA #1 tempX := 1 CLC ADC &a tempX := tempX + a; TAY save tempX into Y reg. LDA &temp12 temp4 := temp12; LDA &temp25 temp4 := temp4 * temp25; JSR &runtimeMultiply call Pascal runtime STA &temp temp4 := returnValue TSX remove arguments from stack TYA restore tempX from Y ADC &temp4 tempX := tempX + temp4; ADC &temp31 tempX := tempX + temp31; ADC &x tempX := tempX + x; STA &x x := tempX; TSX free 7 one byte temps TXA ADC #7 TAX

37 6502 stack pointer register:
TSX allocate 7 one byte temps TXA SEC SBC #7 TAX TXS LDA &b temp11 := b; CLC ADC &c temp11 := temp11 + c; PHA push temp11 PHA reserve space for return value by pushing dummy value JSR &F1 call F1 TSX ?? save return value into A INX remove return value from stack INX remove arguments from stack STA &temp12 temp12 := returnValue; LDA #3 push 3 PHA LDA #2 push 2 JSR &F3 call F3 TSX remove arguments from stack INX STA &temp21 temp21 := returnValue; LDA &d temp22 := d; ADC &e temp22 := temp22 + e; ADC &temp temp22 := temp22 + temp21; STA &temp22 LDA # push 4 JSR &F call F4 TSX remove arguments from stack STA &temp temp23 := returnValue; LDA &f temp24 := f; ADC &temp temp24 := temp24 + temp23; PHA push temp24 LDA &temp22 push temp22 JSR &f2 call F2 TSX remove arguments from stack STA &temp25 temp25 := returnValue; Passing return value on stack for F1, and in accumulator for F2, F3, F4, F5 x := 1 + a + F1(b + c) * F2(d + e + F3(2, 3), f + F4(4)) + F5(5) + x; LDA #5 push 5 PHA JSR &F5 call F5 TSX remove arguments from stack INX TXS STA &temp31 temp31 := returnValue; LDA #1 tempX := 1 CLC ADC &a tempX := tempX + a; TAY save tempX into Y reg. LDA &temp12 temp4 := temp12; LDA &temp25 temp4 := temp4 * temp25; JSR &runtimeMultiply call Pascal runtime STA &temp temp4 := returnValue TSX remove arguments from stack TYA restore tempX from Y ADC &temp4 tempX := tempX + temp4; ADC &temp31 tempX := tempX + temp31; ADC &x tempX := tempX + x; STA &x x := tempX; TSX free 7 one byte temps TXA ADC #7 TAX ... ?? $01EC $01EB $01EA $01E9 ↔ temp $01E8 ↔ temp $01E7 ↔ temp $01E6 ↔ temp $01E5 ↔ temp $01E4 ↔ temp $01E3 ↔ temp a1 $01E2 ↔ 1st argument r $01E1 ↔ return value S($E0) → $01E0 $01DF 6502 stack pointer register: S

38 6502 stack pointer register:
TSX allocate 7 one byte temps TXA SEC SBC #7 TAX TXS LDA &b temp11 := b; CLC ADC &c temp11 := temp11 + c; PHA push temp11 PHA reserve space for return value by pushing dummy value JSR &F1 call F1 TSX ?? save return value into A INX remove return value from stack INX remove arguments from stack STA &temp12 temp12 := returnValue; LDA #3 push 3 PHA LDA #2 push 2 JSR &F3 call F3 TSX remove arguments from stack INX STA &temp21 temp21 := returnValue; LDA &d temp22 := d; ADC &e temp22 := temp22 + e; ADC &temp temp22 := temp22 + temp21; STA &temp22 LDA # push 4 JSR &F call F4 TSX remove arguments from stack STA &temp temp23 := returnValue; LDA &f temp24 := f; ADC &temp temp24 := temp24 + temp23; PHA push temp24 LDA &temp22 push temp22 JSR &f2 call F2 TSX remove arguments from stack STA &temp25 temp25 := returnValue; Passing return value on stack for F1, and in accumulator for F2, F3, F4, F5 x := 1 + a + F1(b + c) * F2(d + e + F3(2, 3), f + F4(4)) + F5(5) + x; LDA #5 push 5 PHA JSR &F5 call F5 TSX remove arguments from stack INX TXS STA &temp31 temp31 := returnValue; LDA #1 tempX := 1 CLC ADC &a tempX := tempX + a; TAY save tempX into Y reg. LDA &temp12 temp4 := temp12; LDA &temp25 temp4 := temp4 * temp25; JSR &runtimeMultiply call Pascal runtime STA &temp temp4 := returnValue TSX remove arguments from stack TYA restore tempX from Y ADC &temp4 tempX := tempX + temp4; ADC &temp31 tempX := tempX + temp31; ADC &x tempX := tempX + x; STA &x x := tempX; TSX free 7 one byte temps TXA ADC #7 TAX ... ?? $01EC $01EB $01EA $01E9 ↔ temp $01E8 ↔ temp $01E7 ↔ temp $01E6 ↔ temp $01E5 ↔ temp $01E4 ↔ temp $01E3 ↔ temp $100+S+2 a1 $01E2 ↔ 1st argument $100+S+1 r $01E1 ↔ return value S($E0) → $01E0 $01DF 6502 stack pointer register: S

39 6502 stack pointer register:
TSX allocate 7 one byte temps TXA SEC SBC #7 TAX TXS LDA &b temp11 := b; CLC ADC &c temp11 := temp11 + c; PHA push temp11 PHA reserve space for return value by pushing dummy value JSR &F1 call F1 TSX ?? save return value into A INX remove return value from stack INX remove arguments from stack STA &temp12 temp12 := returnValue; LDA #3 push 3 PHA LDA #2 push 2 JSR &F3 call F3 TSX remove arguments from stack INX STA &temp21 temp21 := returnValue; LDA &d temp22 := d; ADC &e temp22 := temp22 + e; ADC &temp temp22 := temp22 + temp21; STA &temp22 LDA # push 4 JSR &F call F4 TSX remove arguments from stack STA &temp temp23 := returnValue; LDA &f temp24 := f; ADC &temp temp24 := temp24 + temp23; PHA push temp24 LDA &temp22 push temp22 JSR &f2 call F2 TSX remove arguments from stack STA &temp25 temp25 := returnValue; Passing return value on stack for F1, and in accumulator for F2, F3, F4, F5 x := 1 + a + F1(b + c) * F2(d + e + F3(2, 3), f + F4(4)) + F5(5) + x; LDA #5 push 5 PHA JSR &F5 call F5 TSX remove arguments from stack INX TXS STA &temp31 temp31 := returnValue; LDA #1 tempX := 1 CLC ADC &a tempX := tempX + a; TAY save tempX into Y reg. LDA &temp12 temp4 := temp12; LDA &temp25 temp4 := temp4 * temp25; JSR &runtimeMultiply call Pascal runtime STA &temp temp4 := returnValue TSX remove arguments from stack TYA restore tempX from Y ADC &temp4 tempX := tempX + temp4; ADC &temp31 tempX := tempX + temp31; ADC &x tempX := tempX + x; STA &x x := tempX; TSX free 7 one byte temps TXA ADC #7 TAX ... ?? $01EC $01EB $01EA $01E9 ↔ temp $01E8 ↔ temp $01E7 ↔ temp $01E6 ↔ temp $01E5 ↔ temp $01E4 ↔ temp $01E3 ↔ temp $102+S a1 $01E2 ↔ 1st argument $101+S r $01E1 ↔ return value S($E0) → $01E0 $01DF 6502 stack pointer register: S

40 Not a valid 6502 instruction
TSX allocate 7 one byte temps TXA SEC SBC #7 TAX TXS LDA &b temp11 := b; CLC ADC &c temp11 := temp11 + c; PHA push temp11 PHA reserve space for return value by pushing dummy value JSR &F1 call F1 TSX LDA $101 + S save return value into A INX remove return value from stack INX remove arguments from stack STA &temp12 temp12 := returnValue; LDA #3 push 3 PHA LDA #2 push 2 JSR &F3 call F3 TSX remove arguments from stack INX STA &temp21 temp21 := returnValue; LDA &d temp22 := d; ADC &e temp22 := temp22 + e; ADC &temp temp22 := temp22 + temp21; STA &temp22 LDA # push 4 JSR &F call F4 TSX remove arguments from stack STA &temp temp23 := returnValue; LDA &f temp24 := f; ADC &temp temp24 := temp24 + temp23; PHA push temp24 LDA &temp22 push temp22 JSR &f2 call F2 TSX remove arguments from stack STA &temp25 temp25 := returnValue; Passing return value on stack for F1, and in accumulator for F2, F3, F4, F5 x := 1 + a + F1(b + c) * F2(d + e + F3(2, 3), f + F4(4)) + F5(5) + x; LDA #5 push 5 PHA JSR &F5 call F5 TSX remove arguments from stack INX TXS STA &temp31 temp31 := returnValue; LDA #1 tempX := 1 CLC ADC &a tempX := tempX + a; TAY save tempX into Y reg. LDA &temp12 temp4 := temp12; LDA &temp25 temp4 := temp4 * temp25; JSR &runtimeMultiply call Pascal runtime STA &temp temp4 := returnValue TSX remove arguments from stack TYA restore tempX from Y ADC &temp4 tempX := tempX + temp4; ADC &temp31 tempX := tempX + temp31; ADC &x tempX := tempX + x; STA &x x := tempX; TSX free 7 one byte temps TXA ADC #7 TAX Not a valid 6502 instruction ... ?? $01EC $01EB $01EA $01E9 ↔ temp $01E8 ↔ temp $01E7 ↔ temp $01E6 ↔ temp $01E5 ↔ temp $01E4 ↔ temp $01E3 ↔ temp $102+S a1 $01E2 ↔ 1st argument $101+S r $01E1 ↔ return value S($E0) → $01E0 $01DF 6502 stack pointer register: S

41 Not a valid 6502 instruction
TSX allocate 7 one byte temps TXA SEC SBC #7 TAX TXS LDA &b temp11 := b; CLC ADC &c temp11 := temp11 + c; PHA push temp11 PHA reserve space for return value by pushing dummy value JSR &F1 call F1 TSX LDA $101 + S save return value into A INX remove return value from stack INX remove arguments from stack STA &temp12 temp12 := returnValue; LDA #3 push 3 PHA LDA #2 push 2 JSR &F3 call F3 TSX remove arguments from stack INX STA &temp21 temp21 := returnValue; LDA &d temp22 := d; ADC &e temp22 := temp22 + e; ADC &temp temp22 := temp22 + temp21; STA &temp22 LDA # push 4 JSR &F call F4 TSX remove arguments from stack STA &temp temp23 := returnValue; LDA &f temp24 := f; ADC &temp temp24 := temp24 + temp23; PHA push temp24 LDA &temp22 push temp22 JSR &f2 call F2 TSX remove arguments from stack STA &temp25 temp25 := returnValue; Passing return value on stack for F1, and in accumulator for F2, F3, F4, F5 x := 1 + a + F1(b + c) * F2(d + e + F3(2, 3), f + F4(4)) + F5(5) + x; LDA #5 push 5 PHA JSR &F5 call F5 TSX remove arguments from stack INX TXS STA &temp31 temp31 := returnValue; LDA #1 tempX := 1 CLC ADC &a tempX := tempX + a; TAY save tempX into Y reg. LDA &temp12 temp4 := temp12; LDA &temp25 temp4 := temp4 * temp25; JSR &runtimeMultiply call Pascal runtime STA &temp temp4 := returnValue TSX remove arguments from stack TYA restore tempX from Y ADC &temp4 tempX := tempX + temp4; ADC &temp31 tempX := tempX + temp31; ADC &x tempX := tempX + x; STA &x x := tempX; TSX free 7 one byte temps TXA ADC #7 TAX 6502 indexed load into A: LDA $xxxx,X LDA $xxxx,Y A := ($xxxx + X)^ A := ($xxxx + Y)^ Not a valid 6502 instruction ... ?? $01EC $01EB $01EA $01E9 ↔ temp $01E8 ↔ temp $01E7 ↔ temp $01E6 ↔ temp $01E5 ↔ temp $01E4 ↔ temp $01E3 ↔ temp $102+S a1 $01E2 ↔ 1st argument $101+S r $01E1 ↔ return value S($E0) → $01E0 $01DF 6502 stack pointer register: S

42 We already have current content of S register stored in X register!
TSX allocate 7 one byte temps TXA SEC SBC #7 TAX TXS LDA &b temp11 := b; CLC ADC &c temp11 := temp11 + c; PHA push temp11 PHA reserve space for return value by pushing dummy value JSR &F1 call F1 TSX LDA $101 + S save return value into A INX remove return value from stack INX remove arguments from stack STA &temp12 temp12 := returnValue; LDA #3 push 3 PHA LDA #2 push 2 JSR &F3 call F3 TSX remove arguments from stack INX STA &temp21 temp21 := returnValue; LDA &d temp22 := d; ADC &e temp22 := temp22 + e; ADC &temp temp22 := temp22 + temp21; STA &temp22 LDA # push 4 JSR &F call F4 TSX remove arguments from stack STA &temp temp23 := returnValue; LDA &f temp24 := f; ADC &temp temp24 := temp24 + temp23; PHA push temp24 LDA &temp22 push temp22 JSR &f2 call F2 TSX remove arguments from stack STA &temp25 temp25 := returnValue; Passing return value on stack for F1, and in accumulator for F2, F3, F4, F5 x := 1 + a + F1(b + c) * F2(d + e + F3(2, 3), f + F4(4)) + F5(5) + x; We already have current content of S register stored in X register! LDA #5 push 5 PHA JSR &F5 call F5 TSX remove arguments from stack INX TXS STA &temp31 temp31 := returnValue; LDA #1 tempX := 1 CLC ADC &a tempX := tempX + a; TAY save tempX into Y reg. LDA &temp12 temp4 := temp12; LDA &temp25 temp4 := temp4 * temp25; JSR &runtimeMultiply call Pascal runtime STA &temp temp4 := returnValue TSX remove arguments from stack TYA restore tempX from Y ADC &temp4 tempX := tempX + temp4; ADC &temp31 tempX := tempX + temp31; ADC &x tempX := tempX + x; STA &x x := tempX; TSX free 7 one byte temps TXA ADC #7 TAX 6502 indexed load into A: LDA $xxxx,X LDA $xxxx,Y A := ($xxxx + X)^ A := ($xxxx + Y)^ Not a valid 6502 instruction ... ?? $01EC $01EB $01EA $01E9 ↔ temp $01E8 ↔ temp $01E7 ↔ temp $01E6 ↔ temp $01E5 ↔ temp $01E4 ↔ temp $01E3 ↔ temp $102+S a1 $01E2 ↔ 1st argument $101+S r $01E1 ↔ return value S($E0) → $01E0 $01DF 6502 stack pointer register: S

43 We already have current content of S register stored in X register!
TSX allocate 7 one byte temps TXA SEC SBC #7 TAX TXS LDA &b temp11 := b; CLC ADC &c temp11 := temp11 + c; PHA push temp11 PHA reserve space for return value by pushing dummy value JSR &F1 call F1 TSX LDA $101,X save return value into A INX remove return value from stack INX remove arguments from stack STA &temp12 temp12 := returnValue; LDA #3 push 3 PHA LDA #2 push 2 JSR &F3 call F3 TSX remove arguments from stack INX STA &temp21 temp21 := returnValue; LDA &d temp22 := d; ADC &e temp22 := temp22 + e; ADC &temp temp22 := temp22 + temp21; STA &temp22 LDA # push 4 JSR &F call F4 TSX remove arguments from stack STA &temp temp23 := returnValue; LDA &f temp24 := f; ADC &temp temp24 := temp24 + temp23; PHA push temp24 LDA &temp22 push temp22 JSR &f2 call F2 TSX remove arguments from stack STA &temp25 temp25 := returnValue; Passing return value on stack for F1, and in accumulator for F2, F3, F4, F5 x := 1 + a + F1(b + c) * F2(d + e + F3(2, 3), f + F4(4)) + F5(5) + x; We already have current content of S register stored in X register! LDA #5 push 5 PHA JSR &F5 call F5 TSX remove arguments from stack INX TXS STA &temp31 temp31 := returnValue; LDA #1 tempX := 1 CLC ADC &a tempX := tempX + a; TAY save tempX into Y reg. LDA &temp12 temp4 := temp12; LDA &temp25 temp4 := temp4 * temp25; JSR &runtimeMultiply call Pascal runtime STA &temp temp4 := returnValue TSX remove arguments from stack TYA restore tempX from Y ADC &temp4 tempX := tempX + temp4; ADC &temp31 tempX := tempX + temp31; ADC &x tempX := tempX + x; STA &x x := tempX; TSX free 7 one byte temps TXA ADC #7 TAX LDA $101 + S 6502 indexed load into A: LDA $xxxx,X LDA $xxxx,Y A := ($xxxx + X)^ A := ($xxxx + Y)^ Not a valid 6502 instruction ... ?? $01EC $01EB $01EA $01E9 ↔ temp $01E8 ↔ temp $01E7 ↔ temp $01E6 ↔ temp $01E5 ↔ temp $01E4 ↔ temp $01E3 ↔ temp $102+S a1 $01E2 ↔ 1st argument $101+S r $01E1 ↔ return value S($E0) → $01E0 $01DF 6502 stack pointer register: S

44 Assign memory locations to temporary variables
TSX allocate 7 one byte temps TXA SEC SBC #7 TAX TXS LDA &b temp11 := b; CLC ADC &c temp11 := temp11 + c; PHA push temp11 PHA reserve space for return value by pushing dummy value JSR &F1 call F1 TSX LDA $101,X save return value into A INX remove return value from stack INX remove arguments from stack STA &temp12 temp12 := returnValue; LDA #3 push 3 PHA LDA #2 push 2 JSR &F3 call F3 TSX remove arguments from stack INX STA &temp21 temp21 := returnValue; LDA &d temp22 := d; ADC &e temp22 := temp22 + e; ADC &temp temp22 := temp22 + temp21; STA &temp22 LDA # push 4 JSR &F call F4 TSX remove arguments from stack STA &temp temp23 := returnValue; LDA &f temp24 := f; ADC &temp temp24 := temp24 + temp23; PHA push temp24 LDA &temp22 push temp22 JSR &f2 call F2 TSX remove arguments from stack STA &temp25 temp25 := returnValue; Assign memory locations to temporary variables Passing return value on stack for F1, and in accumulator for F2, F3, F4, F5 x := 1 + a + F1(b + c) * F2(d + e + F3(2, 3), f + F4(4)) + F5(5) + x; LDA #5 push 5 PHA JSR &F5 call F5 TSX remove arguments from stack INX TXS STA &temp31 temp31 := returnValue; LDA #1 tempX := 1 CLC ADC &a tempX := tempX + a; TAY save tempX into Y reg. LDA &temp12 temp4 := temp12; LDA &temp25 temp4 := temp4 * temp25; JSR &runtimeMultiply call Pascal runtime STA &temp temp4 := returnValue TSX remove arguments from stack TYA restore tempX from Y ADC &temp4 tempX := tempX + temp4; ADC &temp31 tempX := tempX + temp31; ADC &x tempX := tempX + x; STA &x x := tempX; TSX free 7 one byte temps TXA ADC #7 TAX ... ?? $01EC $01EB $01EA +7 $01E9 ↔ temp12 +6 $01E8 ↔ temp21 +5 $01E7 ↔ temp22 +4 $01E6 ↔ temp23 +3 $01E5 ↔ temp25 +2 $01E4 ↔ temp31 +1 $01E3 ↔ temp4 S($E0) → a1 $01E2 r $01E1 $01E0 $01DF

45 Assign memory locations to temporary variables
TSX allocate 7 one byte temps TXA SEC SBC #7 TAX TXS LDA &b temp11 := b; CLC ADC &c temp11 := temp11 + c; PHA push temp11 PHA reserve space for return value by pushing dummy value JSR &F1 call F1 TSX LDA $101,X save return value into A INX remove return value from stack INX remove arguments from stack STA $107,X temp12 := returnValue; LDA #3 push 3 PHA LDA #2 push 2 JSR &F3 call F3 TSX remove arguments from stack INX STA $106,X temp21 := returnValue; LDA &d temp22 := d; ADC &e temp22 := temp22 + e; ADC $106,X temp22 := temp22 + temp21; STA $105,X LDA # push 4 JSR &F call F4 TSX remove arguments from stack STA $104,X temp23 := returnValue; LDA &f temp24 := f; ADC $104,X temp24 := temp24 + temp23; PHA push temp24 LDA $105,X push temp22 JSR &f2 call F2 TSX remove arguments from stack STA $103,X temp25 := returnValue; Assign memory locations to temporary variables x := 1 + a + F1(b + c) * F2(d + e + F3(2, 3), f + F4(4)) + F5(5) + x; LDA #5 push 5 PHA JSR &F5 call F5 TSX remove arguments from stack INX TXS STA $102,X temp31 := returnValue; LDA #1 tempX := 1 CLC ADC &a tempX := tempX + a; TAY save tempX into Y reg. LDA $107,X temp4 := temp12; LDA $103,X temp4 := temp4 * temp25; JSR &runtimeMultiply call Pascal runtime STA $101,X temp4 := returnValue TSX remove arguments from stack TYA restore tempX from Y ADC $101,X tempX := tempX + temp4; ADC $102,X tempX := tempX + temp31; ADC &x tempX := tempX + x; STA &x x := tempX; TSX free 7 one byte temps TXA ADC #7 TAX ... ?? $01EC $01EB $01EA +7 $01E9 ↔ temp12 +6 $01E8 ↔ temp21 +5 $01E7 ↔ temp22 +4 $01E6 ↔ temp23 +3 $01E5 ↔ temp25 +2 $01E4 ↔ temp31 +1 $01E3 ↔ temp4 S($E0) → a1 $01E2 r $01E1 $01E0 $01DF

46 Final variant = 89 instructions in 6502 CPU machine code
TSX allocate 7 one byte temps TXA SEC SBC #7 TAX TXS LDA &b temp11 := b; CLC ADC &c temp11 := temp11 + c; PHA push temp11 PHA reserve space for return value by pushing dummy value JSR &F1 call F1 TSX LDA $101,X save return value into A INX remove return value from stack INX remove arguments from stack STA $107,X temp12 := returnValue; LDA #3 push 3 PHA LDA #2 push 2 JSR &F3 call F3 TSX remove arguments from stack INX STA $106,X temp21 := returnValue; LDA &d temp22 := d; ADC &e temp22 := temp22 + e; ADC $106,X temp22 := temp22 + temp21; STA $105,X LDA # push 4 JSR &F call F4 TSX remove arguments from stack STA $104,X temp23 := returnValue; LDA &f temp24 := f; ADC $104,X temp24 := temp24 + temp23; PHA push temp24 LDA $105,X push temp22 JSR &f2 call F2 TSX remove arguments from stack STA $103,X temp25 := returnValue; Single command in Pascal: x := 1 + a + F1(b + c) * F2(d + e + F3(2, 3), f + F4(4)) + F5(5) + x; LDA #5 push 5 PHA JSR &F5 call F5 TSX remove arguments from stack INX TXS STA $102,X temp31 := returnValue; LDA #1 tempX := 1 CLC ADC &a tempX := tempX + a; TAY save tempX into Y reg. LDA $107,X temp4 := temp12; LDA $103,X temp4 := temp4 * temp25; JSR &runtimeMultiply call Pascal runtime STA $101,X temp4 := returnValue TSX remove arguments from stack TYA restore tempX from Y ADC $101,X tempX := tempX + temp4; ADC $102,X tempX := tempX + temp31; ADC &x tempX := tempX + x; STA &x x := tempX; TSX free 7 one byte temps TXA ADC #7 TAX Final variant = 89 instructions in 6502 CPU machine code

47 X86-* Registers: More Registers → More Freedom For Programmer/Compiler
EAX AX AH AL EAX EBX ECX EDX ESI EDI EBP x86 (IA-32)

48 x86: OP target, source MOV target, source → target := source
OP target, source → target := target OP source

49 x86: OP target, source MOV target, source → target := source
LD? #$xx LD? $xxxx LD? $xxxx,? ST? $xxxx ST? $xxxx,X T?? PHA PLA MOV r, imm MOV r, [addr] MOV r2, [r1 + addr] MOV [addr], r MOV [r1 + addr], r2 MOV r2, r1 PUSH r POP r MOV target, source → target := source OP target, source → target := target OP source

50 x86: OP target, source MOV target, source → target := source
LD? #$xx LD? $xxxx LD? $xxxx,? ST? $xxxx ST? $xxxx,X T?? PHA PLA MOV r, imm MOV r, [addr] MOV r2, [r1 + addr] MOV [addr], r MOV [r1 + addr], r2 MOV r2, r1 PUSH r POP r Most complex x86 addressing mode: [r1 + (r2 * scale) + imm] scale = immediate value: 1, 2, 4, 8 MOV target, source → target := source OP target, source → target := target OP source

51 x86: Accessing Array of Records (pArr^[1].b?)
LD? #$xx LD? $xxxx LD? $xxxx,? ST? $xxxx ST? $xxxx,X T?? PHA PLA MOV r, imm MOV r, [addr] MOV r2, [r1 + addr] MOV [addr], r MOV [r1 + addr], r2 MOV r2, r1 PUSH r POP r Most complex x86 addressing mode: [r1 + (r2 * scale) + imm] scale = immediate value: 1, 2, 4, 8 type TRecord = record a : longword; { offset 0 } b : longword; { offset 4 } c : byte; { offset 8 } end; var pArr : ^array[0..15] of TRecord; MOV target, source → target := source OP target, source → target := target OP source

52 x86: Accessing Array of Records (pArr^[1].b?)
LD? #$xx LD? $xxxx LD? $xxxx,? ST? $xxxx ST? $xxxx,X T?? PHA PLA MOV r, imm MOV r, [addr] MOV r2, [r1 + addr] MOV [addr], r MOV [r1 + addr], r2 MOV r2, r1 PUSH r POP r ... 17 $00B91017 [2].b 16 $00B91016 15 $00B91015 14 $00B91014 13 $00B91013 [2].a 12 $00B91012 [1].c 11 $00B91011 10 $00B91010 0F $00B9100F 0E $00B9100E [1].b 0D $00B9100D 0C $00B9100C 0B $00B9100B 0A $00B9100A [1].a 09 $00B91009 [0].c 08 $00B91008 07 $00B91007 06 $00B91006 05 $00B91005 [0].b 04 $00B91004 03 $00B91003 02 $00B91002 01 $00B91001 [0].a 00 $00B91000 ← pArr Most complex x86 addressing mode: [r1 + (r2 * scale) + imm] scale = immediate value: 1, 2, 4, 8 type TRecord = record a : longword; { offset 0 } b : longword; { offset 4 } c : byte; { offset 8 } end; var pArr : ^array[0..15] of TRecord; If Pascal compiler does not align records in array. MOV target, source → target := source OP target, source → target := target OP source

53 x86: Accessing Array of Records (pArr^[1].b?)
LD? #$xx LD? $xxxx LD? $xxxx,? ST? $xxxx ST? $xxxx,X T?? PHA PLA MOV r, imm MOV r, [addr] MOV r2, [r1 + addr] MOV [addr], r MOV [r1 + addr], r2 MOV r2, r1 PUSH r POP r ... 17 $00B91017 [2].b 16 $00B91016 15 $00B91015 14 $00B91014 13 $00B91013 [2].a 12 $00B91012 [1].c 11 $00B91011 10 $00B91010 0F $00B9100F 0E $00B9100E [1].b 0D $00B9100D .b = ? 0C $00B9100C 0B $00B9100B 0A $00B9100A [1].a 09 $00B [1] = ? [0].c 08 $00B91008 07 $00B91007 06 $00B91006 05 $00B91005 [0].b 04 $00B91004 03 $00B91003 02 $00B91002 01 $00B91001 [0].a 00 $00B91000 ← EAX=pArr Most complex x86 addressing mode: [r1 + (r2 * scale) + imm] scale = immediate value: 1, 2, 4, 8 type TRecord = record a : longword; { offset 0 } b : longword; { offset 4 } c : byte; { offset 8 } end; var pArr : ^array[0..15] of TRecord; MOV target, source → target := source OP target, source → target := target OP source

54 x86: Accessing Array of Records (pArr^[1].b?)
LD? #$xx LD? $xxxx LD? $xxxx,? ST? $xxxx ST? $xxxx,X T?? PHA PLA MOV r, imm MOV r, [addr] MOV r2, [r1 + addr] MOV [addr], r MOV [r1 + addr], r2 MOV r2, r1 PUSH r POP r ... 17 $00B91017 [2].b 16 $00B91016 15 $00B91015 14 $00B91014 13 $00B91013 [2].a 12 $00B91012 [1].c 11 $00B91011 10 $00B91010 0F $00B9100F 0E $00B9100E [1].b 0D $00B9100D +4 0C $00B9100C 0B $00B9100B 0A $00B9100A [1].a 09 $00B ECX=1*9 [0].c 08 $00B91008 07 $00B91007 06 $00B91006 05 $00B91005 [0].b 04 $00B91004 03 $00B91003 02 $00B91002 01 $00B91001 [0].a 00 $00B91000 ← EAX=pArr Most complex x86 addressing mode: [r1 + (r2 * scale) + imm] scale = immediate value: 1, 2, 4, 8 type TRecord = record a : longword; { offset 0 } b : longword; { offset 4 } c : byte; { offset 8 } end; var pArr : ^array[0..15] of TRecord; MOV target, source → target := source OP target, source → target := target OP source

55 x86: Accessing Array of Records (pArr^[1].b?)
LD? #$xx LD? $xxxx LD? $xxxx,? ST? $xxxx ST? $xxxx,X T?? PHA PLA MOV r, imm MOV r, [addr] MOV r2, [r1 + addr] MOV [addr], r MOV [r1 + addr], r2 MOV r2, r1 PUSH r POP r ... 17 $00B91017 [2].b 16 $00B91016 15 $00B91015 14 $00B91014 13 $00B91013 [2].a 12 $00B91012 [1].c 11 $00B91011 10 $00B91010 0F $00B9100F 0E $00B9100E [1].b 0D $00B9100D +4 0C $00B9100C 0B $00B9100B 0A $00B9100A [1].a 09 $00B ECX=1*9 [0].c 08 $00B91008 07 $00B91007 06 $00B91006 05 $00B91005 [0].b 04 $00B91004 03 $00B91003 02 $00B91002 01 $00B91001 [0].a 00 $00B91000 ← EAX=pArr Most complex x86 addressing mode: [r1 + (r2 * scale) + imm] scale = immediate value: 1, 2, 4, 8 type TRecord = record a : longword; { offset 0 } b : longword; { offset 4 } c : byte; { offset 8 } end; var pArr : ^array[0..15] of TRecord; MOV ECX, 1 { 1 = index into array } IMUL ECX, 9 { 9 = size of record } MOV target, source → target := source OP target, source → target := target OP source

56 x86: Accessing Array of Records (pArr^[1].b?)
LD? #$xx LD? $xxxx LD? $xxxx,? ST? $xxxx ST? $xxxx,X T?? PHA PLA MOV r, imm MOV r, [addr] MOV r2, [r1 + addr] MOV [addr], r MOV [r1 + addr], r2 MOV r2, r1 PUSH r POP r ... 17 $00B91017 [2].b 16 $00B91016 15 $00B91015 14 $00B91014 13 $00B91013 [2].a 12 $00B91012 [1].c 11 $00B91011 10 $00B91010 0F $00B9100F 0E $00B9100E [1].b 0D $00B9100D +4 0C $00B9100C 0B $00B9100B 0A $00B9100A [1].a 09 $00B ECX=1*9 [0].c 08 $00B91008 07 $00B91007 06 $00B91006 05 $00B91005 [0].b 04 $00B91004 03 $00B91003 02 $00B91002 01 $00B91001 [0].a 00 $00B91000 ← EAX=pArr Most complex x86 addressing mode: [r1 + (r2 * scale) + imm] scale = immediate value: 1, 2, 4, 8 type TRecord = record a : longword; { offset 0 } b : longword; { offset 4 } c : byte; { offset 8 } end; var pArr : ^array[0..15] of TRecord; MOV ECX, 1 { 1 = index into array } IMUL ECX, 9 { 9 = size of record } MOV EBX, [EAX + ECX + 4] { 4 = offset of b } MOV target, source → target := source OP target, source → target := target OP source

57 x86: Accessing Array of Records (pArr^[1].b?)
LD? #$xx LD? $xxxx LD? $xxxx,? ST? $xxxx ST? $xxxx,X T?? PHA PLA MOV r, imm MOV r, [addr] MOV r2, [r1 + addr] MOV [addr], r MOV [r1 + addr], r2 MOV r2, r1 PUSH r POP r ... 17 $00B91017 16 $00B91016 15 $00B91015 [2].b 14 $00B91014 13 $00B91013 12 $00B91012 11 $00B91011 [2].a 10 $00B91010 0F $00B9100F 0E $00B9100E 0D $00B9100D +4 [1].b 0C $00B9100C 0B $00B9100B 0A $00B9100A 09 $00B91009 [1].a 08 $00B =1*8 07 $00B91007 06 $00B91006 05 $00B91005 [0].b 04 $00B91004 03 $00B91003 02 $00B91002 01 $00B91001 [0].a 00 $00B91000 ← EAX=pArr Most complex x86 addressing mode: [r1 + (r2 * scale) + imm] scale = immediate value: 1, 2, 4, 8 type TRecord = record a : longword; { offset 0 } b : longword; { offset 4 } end; var pArr : ^array[0..15] of TRecord; MOV ECX, 1 { 1 = index into array } MOV EBX, [EAX + ECX * 8 + 4] { 8 = size of record } { 4 = offset of b } MOV target, source → target := source OP target, source → target := target OP source

58 x86: OP target, source MOV target, source → target := source
LD? #$xx LD? $xxxx LD? $xxxx,? ST? $xxxx ST? $xxxx,X T?? PHA PLA MOV r, imm MOV r, [addr] MOV r2, [r1 + addr] MOV [addr], r MOV [r1 + addr], r2 MOV r2, r1 PUSH r POP r Most complex x86 addressing mode: [r1 + (r2 * scale) + imm] scale = immediate value: 1, 2, 4, 8 MOV target, source → target := source OP target, source → target := target OP source

59 x86: OP target, source MOV target, source → target := source
LD? #$xx LD? $xxxx LD? $xxxx,? ST? $xxxx ST? $xxxx,X T?? PHA PLA MOV r, imm MOV r, [addr] MOV r2, [r1 + addr] MOV [addr], r MOV [r1 + addr], r2 MOV r2, r1 PUSH r POP r ADD r, reg/imm/addr ADC r, reg/imm/addr SUB r, reg/imm/addr SBB r, reg/imm/addr IMUL r, reg/imm/addr IDIV r, reg/imm/addr OR r, reg/imm/addr AND r, reg/imm/addr XOR r, reg/imm/addr NOT r SHR reg/addr, imm/CL SAR reg/addr, imm/CL SHL reg/addr, imm/CL r := r + reg/imm/addr EFlags.Carry := result.32 r := r + reg/imm/addr + EFlags.Carry Most complex x86 addressing mode: [r1 + (r2 * scale) + imm] scale = immediate value: 1, 2, 4, 8 MOV target, source → target := source OP target, source → target := target OP source

60 x86: Flags LD? #$xx LD? $xxxx LD? $xxxx,? ST? $xxxx ST? $xxxx,X T??
PHA PLA MOV r, imm MOV r, [addr] MOV r2, [r1 + addr] MOV [addr], r MOV [r1 + addr], r2 MOV r2, r1 PUSH r POP r ADD r, reg/imm/addr ADC r, reg/imm/addr SUB r, reg/imm/addr SBB r, reg/imm/addr IMUL r, reg/imm/addr IDIV r, reg/imm/addr OR r, reg/imm/addr AND r, reg/imm/addr XOR r, reg/imm/addr NOT r SHR reg/addr, imm/CL SAR reg/addr, imm/CL SHL reg/addr, imm/CL r := r + reg/imm/addr EFlags.Carry := result.32 r := r + reg/imm/addr + EFlags.Carry Most complex x86 addressing mode: [r1 + (r2 * scale) + imm] scale = immediate value: 1, 2, 4, 8 EFlags.Sign := target.31 if target = 0 then EFlags.Zero := 1 else EFlags.Zero := 0; CLC STC EFlags.Carry := 0 EFlags.Carry := 1

61 Same Example Targeting x86 Architecture
x := 1 + a + F1(b + c) * F2(d + e + F3(2, 3), f + F4(4)) + F5(5) + x; temp11 := b; temp11 := temp11 + c; push temp11 call F1 temp12 := returnValue; push 3 push 2 call F3 temp21 := returnValue; temp22 := d; temp22 := temp22 + e; temp22 := temp22 + temp21; push 4 call F4 temp23 := returnValue; temp24 := f; temp24 := temp24 + temp23; push temp24 push temp22 call F2 temp25 := returnValue; push 5 call F5 temp31 := returnValue; tempX := 1 tempX := tempX + a; temp4 := temp12; temp4 := temp4 * temp25; tempX := tempX + temp4; tempX := tempX + temp31; tempX := tempX + x; x := tempX;

62 x86 – With “Dynamic Temporary Variable Allocation”
x := 1 + a + F1(b + c) * F2(d + e + F3(2, 3), f + F4(4)) + F5(5) + x; MOV EAX, [&b] temp11 := b; ADD EAX, [&c] temp11 := temp11 + c; PUSH EAX push temp11 CALL &F1 call F1 ADD ESP, 4 PUSH EAX temp12 := returnValue; PUSH push 3 PUSH push 2 CALL &F call F3 ADD ESP, 8 NOP temp21 := returnValue; MOV EBX, [&d] temp22 := d; ADD EBX, [&e] temp22 := temp22 + e; ADD EBX, EAX temp22 := temp22 + temp21; PUSH push 4 CALL &F call F4 NOP temp23 := returnValue; MOV ECX, [&f] temp24 := f; ADD ECX, EAX temp24 := temp24 + temp23; PUSH ECX push temp24 PUSH EBX push temp22 CALL F2 call F2 PUSH EAX temp25 := returnValue; PUSH 5 push 5 CALL &F5 call F5 ADD ESP, 4 NOP temp31 := returnValue; MOV EBX, 1 tempX := 1 ADD EBX, [&a] tempX := tempX + a; POP ECX assign ECX <- temp25 POP EDX temp4 := temp12; IMUL EDX, ECX temp4 := temp4 * temp25; ADD EBX, EDX tempX := tempX + temp4; ADD EBX, EAX tempX := tempX + temp31; ADD EBX, [&x] tempX := tempX + x; MOV [&x], EBX x := tempX;

63 x86 – “temporary variable preallocation”
x := 1 + a + F1(b + c) * F2(d + e + F3(2, 3), f + F4(4)) + F5(5) + x; SUB ESP, 8 MOV EAX, [&b] temp11 := b; ADD EAX, [&c] temp11 := temp11 + c; PUSH EAX push temp11 CALL &F1 call F1 ADD ESP, 4 MOV [ESP + 4], EAX temp12 := returnValue; PUSH push 3 PUSH push 2 CALL &F call F3 ADD ESP, 8 NOP temp21 := returnValue; MOV EBX, [&d] temp22 := d; ADD EBX, [&e] temp22 := temp22 + e; ADD EBX, EAX temp22 := temp22 + temp21; PUSH push 4 CALL &F call F4 NOP temp23 := returnValue; MOV ECX, [&f] temp24 := f; ADD ECX, EAX temp24 := temp24 + temp23; PUSH ECX push temp24 PUSH EBX push temp22 CALL F2 call F2 MOV [ESP], EAX temp25 := returnValue; PUSH 5 push 5 CALL &F5 call F5 ADD ESP, 4 NOP temp31 := returnValue; MOV EBX, 1 tempX := 1 ADD EBX, [&a] tempX := tempX + a; MOV EDX, [ESP + 4] temp4 := temp12; IMUL EDX, [ESP] temp4 := temp4 * temp25; ADD EBX, EDX tempX := tempX + temp4; ADD EBX, EAX tempX := tempX + temp31; ADD EBX, [&x] tempX := tempX + x; MOV [&x], EBX x := tempX; ADD ESP, 8

64 Final variant = 89 instructions in 6502 CPU machine code
x := 1 + a + F1(b + c) * F2(d + e + F3(2, 3), f + F4(4)) + F5(5) + x; SUB ESP, 8 MOV EAX, [&b] temp11 := b; ADD EAX, [&c] temp11 := temp11 + c; PUSH EAX push temp11 CALL &F1 call F1 ADD ESP, 4 MOV [ESP + 4], EAX temp12 := returnValue; PUSH push 3 PUSH push 2 CALL &F call F3 ADD ESP, 8 NOP temp21 := returnValue; MOV EBX, [&d] temp22 := d; ADD EBX, [&e] temp22 := temp22 + e; ADD EBX, EAX temp22 := temp22 + temp21; PUSH push 4 CALL &F call F4 NOP temp23 := returnValue; MOV ECX, [&f] temp24 := f; ADD ECX, EAX temp24 := temp24 + temp23; PUSH ECX push temp24 PUSH EBX push temp22 CALL F2 call F2 MOV [ESP], EAX temp25 := returnValue; PUSH 5 push 5 CALL &F5 call F5 ADD ESP, 4 NOP temp31 := returnValue; MOV EBX, 1 tempX := 1 ADD EBX, [&a] tempX := tempX + a; MOV EDX, [ESP + 4] temp4 := temp12; IMUL EDX, [ESP] temp4 := temp4 * temp25; ADD EBX, EDX tempX := tempX + temp4; ADD EBX, EAX tempX := tempX + temp31; ADD EBX, [&x] tempX := tempX + x; MOV [&x], EBX x := tempX; ADD ESP, 8 Final variant = 36 instructions (excluding NOPs) in x86 CPU machine code Final variant = 89 instructions in 6502 CPU machine code

65 Saving Contents of Registers as Part of a Calling Convention (Save in Prolog/Restore in Epilog): x86 Save EBP at Least, 6502 Save X at Least

66 Typical x86 Prolog and Epilog
PUSH EBP MOV EBP, ESP SUB ESP, ; 10 = total size of all local and temp variables Function/procedure body: EBP + x: function/procedure arguments EBP + 4: return address EBP : old EBP (value saved for the caller) EBP – x: local variables/temporary variables Epilog: MOV ESP, EBP POP EBP RET Pascal procedure P1; var a : longword; b : longword; c : word; begin end;

67 Typical x86 Prolog and Epilog
PUSH EBP MOV EBP, ESP SUB ESP, ; 10 = total size of all local and temp variables Function/procedure body: EBP + x: function/procedure arguments EBP + 4: return address EBP : old EBP (value saved for the caller) EBP – x: local variables/temporary variables Epilog: MOV ESP, EBP POP EBP RET Pascal procedure P1; var a : longword; b : longword; c : word; begin end; Some compilers using a shorter variant on x86: LEAVE


Download ppt "Principles of Computers 18th Lecture"

Similar presentations


Ads by Google