Download presentation
Presentation is loading. Please wait.
1
Principles of Computers 14th Lecture
Pavel Ježek, Ph.D.
2
Oring 16-bit Numbers (e.g. Little Endian)
MSB of A stored at $A001 LSB of A stored at $A000 A15 A14 A13 A12 A11 A10 A9 A8 A7 A6 A5 A4 A3 A2 A1 A0 or MSB of B stored at $B001 LSB of B stored at $B000 B15 B14 B13 B12 B11 B10 B9 B8 B7 B6 B5 B4 B3 B2 B1 B0 = MSB of C stored at $C001 LSB of C stored at $C000 C15 C14 C13 C12 C11 C10 C9 C8 C7 C6 C5 C4 C3 C2 C1 C0
3
Oring 16-bit Numbers (e.g. Little Endian)
MSB of A stored at $A001 LSB of A stored at $A000 A15 A14 A13 A12 A11 A10 A9 A8 A7 A6 A5 A4 A3 A2 A1 A0 or or LDA $A000 ORA $B000 STA $C000 LDA $A001 ORA $B001 STA $C001 MSB of B stored at $B001 LSB of B stored at $B000 B15 B14 B13 B12 B11 B10 B9 B8 B7 B6 B5 B4 B3 B2 B1 B0 = = MSB of C stored at $C001 LSB of C stored at $C000 C15 C14 C13 C12 C11 C10 C9 C8 C7 C6 C5 C4 C3 C2 C1 C0
4
Integer Operations 7654 3210 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;
5
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
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 Signed Integers? = LSB of C stored at $C000 = C8 carry C7 C6 C5 C4 C3 C2 C1 C0 LDA $A000 CLC ADC $B000 STA $C000
7
Adding 16-bit Numbers (e.g. Little Endian)
MSB of A stored at $A001 LSB of A stored at $A000 ADC imm/addr A15 A14 A13 A12 A11 A10 A9 A8 A7 A6 A5 A4 A3 A2 A1 A0 result := A + imm/addr + P.Carry P.Carry := result.8 A := result.7 … result.0 + MSB of B stored at $B001 LSB of B stored at $B000 P.Negative := A.7 if A = 0 then P.Zero := 1 else P.Zero := 0; B15 B14 B13 B12 B11 B10 B9 B8 B7 B6 B5 B4 B3 B2 B1 B0 = MSB of C stored at $C001 LSB of C stored at $C000 C15 C14 C13 C12 C11 C10 C9 C8 C7 C6 C5 C4 C3 C2 C1 C0
8
Adding 16-bit Numbers (e.g. Little Endian)
LSB of A stored at $A000 ADC imm/addr A7 A6 A5 A4 A3 A2 A1 A0 carry result := A + imm/addr + P.Carry P.Carry := result.8 A := result.7 … result.0 + + LSB of B stored at $B000 P.Negative := A.7 if A = 0 then P.Zero := 1 else P.Zero := 0; B7 B6 B5 B4 B3 B2 B1 B0 = LSB of C stored at $C000 = C8 carry C7 C6 C5 C4 C3 C2 C1 C0
9
Adding 16-bit Numbers (e.g. Little Endian)
LSB of A stored at $A000 ADC imm/addr A7 A6 A5 A4 A3 A2 A1 A0 carry result := A + imm/addr + P.Carry P.Carry := result.8 A := result.7 … result.0 + + LDA $A000 CLC ADC $B000 STA $C000 LSB of B stored at $B000 P.Negative := A.7 if A = 0 then P.Zero := 1 else P.Zero := 0; B7 B6 B5 B4 B3 B2 B1 B0 = LSB of C stored at $C000 = C8 carry C7 C6 C5 C4 C3 C2 C1 C0
10
Adding 16-bit Numbers (e.g. Little Endian)
LSB of A stored at $A000 ADC imm/addr A7 A6 A5 A4 A3 A2 A1 A0 carry result := A + imm/addr + P.Carry P.Carry := result.8 A := result.7 … result.0 + + LDA $A000 CLC ADC $B000 STA $C000 LSB of B stored at $B000 P.Negative := A.7 if A = 0 then P.Zero := 1 else P.Zero := 0; B7 B6 B5 B4 B3 B2 B1 B0 = LSB of C stored at $C000 = C8 carry C7 C6 C5 C4 C3 C2 C1 C0 MSB of A stored at $A001 + A15 A14 A13 A12 A11 A10 A9 A8 + MSB of B stored at $B001 B15 B14 B13 B12 B11 B10 B9 B8 = MSB of C stored at $C001 = C16 carry C15 C14 C13 C12 C11 C10 C9 C8
11
Adding 16-bit Numbers (e.g. Little Endian)
LSB of A stored at $A000 ADC imm/addr A7 A6 A5 A4 A3 A2 A1 A0 carry result := A + imm/addr + P.Carry P.Carry := result.8 A := result.7 … result.0 + + LDA $A000 CLC ADC $B000 STA $C000 LSB of B stored at $B000 P.Negative := A.7 if A = 0 then P.Zero := 1 else P.Zero := 0; B7 B6 B5 B4 B3 B2 B1 B0 = LSB of C stored at $C000 = C8 carry C7 C6 C5 C4 C3 C2 C1 C0 MSB of A stored at $A001 + A15 A14 A13 A12 A11 A10 A9 A8 + MSB of B stored at $B001 LDA $A001 ADC $B001 STA $C001 B15 B14 B13 B12 B11 B10 B9 B8 = MSB of C stored at $C001 = C16 carry C15 C14 C13 C12 C11 C10 C9 C8
12
Adding 16-bit Numbers (e.g. Little Endian)
MSB of A stored at $A001 LSB of A stored at $A000 ADC imm/addr A15 A14 A13 A12 A11 A10 A9 A8 A7 A6 A5 A4 A3 A2 A1 A0 result := A + imm/addr + P.Carry P.Carry := result.8 A := result.7 … result.0 + MSB of B stored at $B001 LSB of B stored at $B000 P.Negative := A.7 if A = 0 then P.Zero := 1 else P.Zero := 0; B15 B14 B13 B12 B11 B10 B9 B8 B7 B6 B5 B4 B3 B2 B1 B0 = MSB of C stored at $C001 LSB of C stored at $C000 C15 C14 C13 C12 C11 C10 C9 C8 C7 C6 C5 C4 C3 C2 C1 C0 LDA $A000 CLC ADC $B000 STA $C000 LDA $A001 ADC $B001 STA $C001
13
Integer Operations – Increments and Decrements (only X and Y)
ADC imm/addr result := A + imm/addr + P.Carry P.Carry := result.8 A := result.7 … result.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
14
Integer Operations – Subtraction?
ADC imm/addr result := A + imm/addr + P.Carry P.Carry := result.8 A := result.7 … result.0 P.Negative := A.7 if A = 0 then P.Zero := 1 else P.Zero := 0; unsigned numbers A := value – A 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
15
Integer Operations – Subtraction?
ADC imm/addr result := A + imm/addr + P.Carry P.Carry := result.8 A := result.7 … result.0 P.Negative := A.7 if A = 0 then P.Zero := 1 else P.Zero := 0; A := value – A A := value + (– A) 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
16
Integer Operations – Subtraction? Two’s Complement?
ADC imm/addr result := A + imm/addr + P.Carry P.Carry := result.8 A := result.7 … result.0 P.Negative := A.7 if A = 0 then P.Zero := 1 else P.Zero := 0; unsigned numbers Negative number ↓ signed representation needed A := value – A A := value + (– A) 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
17
Integer Operations – Subtraction? Two’s Complement?
ADC imm/addr result := A + imm/addr + P.Carry P.Carry := result.8 A := result.7 … result.0 P.Negative := A.7 if A = 0 then P.Zero := 1 else P.Zero := 0; unsigned numbers Negative number ↓ signed representation needed A := value – A A := value + (– A) How to represent non-negative number in two’s complement? 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
18
Integer Operations – Subtraction? Via Two’s Complement
ADC imm/addr result := A + imm/addr + P.Carry P.Carry := result.8 A := result.7 … result.0 A := value – A ↓ NOT A INC A ADD value P.Negative := A.7 if A = 0 then P.Zero := 1 else P.Zero := 0; Not a problem, that everything is in unsigned arithmetic A := value – A A := value + (– A) 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
19
Integer Operations – Subtraction? Via Two’s Complement
ADC imm/addr result := A + imm/addr + P.Carry P.Carry := result.8 A := result.7 … result.0 A := value – A ↓ NOT A INC A ADD value A := value – A ↓ EOR #$FF CLC ADC #1 ADC value P.Negative := A.7 if A = 0 then P.Zero := 1 else P.Zero := 0; A := value – A A := value + (– A) 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
20
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
21
Shifts in More Detail ASL A oldA := A A.0 := 0 A.1 := oldA.0
LSR A ROR A ROL A oldA := A A.0 := 0 A.1 := oldA.0 A.2 := oldA.1 … A.7 := oldA.6 P.Carry := oldA.7 A.7 := 0 A.6 := oldA.7 A.5 := oldA.6 A.0 := oldA.1 P.Carry := oldA.0 A.7 := P.Carry Using Carry flag as “ninth” bit as well P.Negative := A.7 if A = 0 then P.Zero := 1 else P.Zero := 0;
22
No Division (div), No Mutiplication (*) Instructions on 6502
23
How To Write/Compile Complex Expressions?
x := 1 + a + F1(b + c) * F2(d + e + F3(2, 3), f + F4(4)) + F5(5) + x;
24
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
25
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;
26
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;
27
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;
28
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;
29
Compiling Multiple Source Files
30
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;
31
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;
32
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;
33
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;
34
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;
35
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;
36
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
37
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
38
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
39
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
40
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;
41
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;
42
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;
43
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
44
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;
45
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;
46
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
47
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
48
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
49
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
50
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
51
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
52
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
53
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
54
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
55
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
56
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
57
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
58
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
59
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
60
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
61
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
62
X86-* Registers: More Registers → More Freedom For Programmer/Compiler
EAX AX AH AL EAX EBX ECX EDX ESI EDI EBP x86 (IA-32)
63
x86: OP target, source MOV target, source → target := source
OP target, source → target := target OP source
64
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
Similar presentations
© 2025 SlidePlayer.com. Inc.
All rights reserved.