1.65k likes | 1.79k Views
It’s better than Lego. Programming Fundamentals 7 Feliks Klu ź niak. Executive summary : We discuss the important concept of “subroutine”. 0 HLT a HALT the machine, after loading MA with a . 1 STO a STORE the accumulator: m[ a ] := A .
E N D
It’s better than Lego Programming Fundamentals 7 Feliks Kluźniak Better than Lego
Executive summary: • We discuss the important concept of “subroutine”. Better than Lego
0 HLT a HALT the machine, after loading MA with a. 1 STO a STORE the accumulator: m[ a ] := A . 2 LOA a LOAD into the accumulator: A := m[ a ] . 3 AND a Bitwise AND: A := A bit_and m[ a ] . 4 OR a Bitwise OR: A := A bit_or m[ a ] . 5 XOR a Bitwise exclusive OR: A := A bit_xor m[ a ] . 6 LSH a Logical SHift(right if a positive, left otherwise) 7 ASH a Arithmetic Shift (with sign-extension) 8 ADD a ADD: A := A + m[ A ] 9 SUB a SUBTRACT: A := A – m[ A ] A JMP a JUMP: IC := a B JMZ a JUMP on Zero: if A = 0 then IC := a fi C JMN a JUMP on Negative: if A < 0 then IC := a fi D CAL a subroutine CALL: m[ a ] := IC; IC := a + 1 E RET a subroutine RETURN: IC := m[ a ] F DEV i DEVICE operation Better than Lego
A computer performs very simple actions. But it performs them quickly and reliably, and never gets tired. A great number of simple actions can add up to something that is very complex indeed. Better than Lego
A computer performs very simple actions. But it performs them quickly and reliably, and never gets tired. A great number of simple actions can add up to something that is very complex indeed. Programming appeals to our creative instincts: it is quite similar to building castles out of wet sand. We create beautiful structures out of almost nothing. Better than Lego
Programming appeals to our creative instincts: it is quite similar to building castles out of wet sand. We create beautiful structures out of almost nothing. Perhaps the greatest appeal of programming is that the computer does exactly what we instruct it to do: this is without precedent in our experience. Better than Lego
Programming appeals to our creative instincts: it is quite similar to building castles out of wet sand. We create beautiful structures out of almost nothing. Perhaps the greatest appeal of programming is that the computer does exactly what we instruct it to do: this is without precedent in our experience. The other, less appealing, side of the coin is that the computer does exactly what we instruct it to do: not less, but also not more. Better than Lego
Programming appeals to our creative instincts: it is quite similar to building castles out of wet sand. We create beautiful structures out of almost nothing. Perhaps the greatest appeal of programming is that the computer does exactly what we instruct it to do: this is without precedent in our experience. The other, less appealing, side of the coin is that the computer does exactly what we instruct it to do: not less, but also not more. But this is all for the good! As any artist will tell you, sculpting is not about waving your hands in the air: it is about the interplay between your vision and the resistance of the medium (the toughness of stone, the heaviness of clay). So we should be glad that programming is by no means easy and devoid of pitfalls. Better than Lego
A computer performs very simple actions. But it performs them quickly and reliably, and never gets tired. A great number of simple actions can add up to something that is very complex indeed. Programming is mostly about trying to tame this complexity. Better than Lego
Programming is mostly about trying to tame complexity. There are three principal tools that we can use: Better than Lego
Programming is mostly about trying to tame complexity. • There are three principal tools that we can use: • Precision and logic. Better than Lego
Programming is mostly about trying to tame complexity. • There are three principal tools that we can use: • Precision and logic. • Subroutines. Better than Lego
Programming is mostly about trying to tame complexity. • There are three principal tools that we can use: • Precision and logic. • Subroutines. • Large-scale modularisation. Better than Lego
Programming is mostly about trying to tame complexity. • There are three principal tools that we can use: • Precision and logic. • Subroutines. • Large-scale modularisation. • Precision and logic is something we can never put aside, and we will have more to say about this aspect of programming throughout the course. Better than Lego
Programming is mostly about trying to tame complexity. • There are three principal tools that we can use: • Precision and logic. • Subroutines. • Large-scale modularisation. • Precision and logic is something we can never put aside, and we will have more to say about this aspect of programming throughout the course. • Subroutines allow us to create a hierarchy of more and more powerful “machine operations”, suited exactly to the task at hand. This lecture is about subroutines. Better than Lego
0 HLT a 1 STO a 2 LOA a 3 AND a 4 OR a 5 XOR a 6 LSH a 7 ASH a 8 ADD a 9 SUB a A JMP a B JMZ a C JMN a D CAL a E RET a F DEV i Suppose that in our program we often want to perform the operation of changing the sign of an integer, i.e., A := - A . Better than Lego
0 HLT a 1 STO a 2 LOA a 3 AND a 4 OR a 5 XOR a 6 LSH a 7 ASH a 8 ADD a 9 SUB a A JMP a B JMZ a C JMN a D CAL a E RET a F DEV i Suppose that in our program we often want to perform the operation of changing the sign of an integer, i.e., A := - A . We don’t have a machine instruction for this, so how can we do it? Better than Lego
0 HLT a 1 STO a 2 LOA a 3 AND a 4 OR a 5 XOR a 6 LSH a 7 ASH a 8 ADD a 9 SUB a A JMP a B JMZ a C JMN a D CAL a E RET a F DEV i Suppose that in our program we often want to perform the operation of changing the sign of an integer, i.e., A := - A . We don’t have a machine instruction for this, so we must do it by subtracting from zero: - A = 0 – A . Better than Lego
0 HLT a 1 STO a 2 LOA a 3 AND a 4 OR a 5 XOR a 6 LSH a 7 ASH a 8 ADD a 9 SUB a A JMP a B JMZ a C JMN a D CAL a E RET a F DEV i Suppose that in our program we often want to perform the operation of changing the sign of an integer, i.e., A := - A . We don’t have a machine instruction for this, so we must do it by subtracting from zero: - A = 0 – A . We could try the following: …. STO TMP ; save the integer LOA ZERO ; load zero SUB TMP ; subtract the integer …. TMP BSS 1 ZERO LIT 0 Better than Lego
0 HLT a 1 STO a 2 LOA a 3 AND a 4 OR a 5 XOR a 6 LSH a 7 ASH a 8 ADD a 9 SUB a A JMP a B JMZ a C JMN a D CAL a E RET a F DEV i We could try the following: …. STO TMP ; save the integer LOA ZERO ; load zero SUB TMP ; subtract the integer …. TMP BSS 1 ZERO LIT 0 That’s quite a lot of code for such an operation, but TMP and ZERO can be shared, so we just write the three instructions everywhere we want to change the sign of an integer. Better than Lego
0 HLT a 1 STO a 2 LOA a 3 AND a 4 OR a 5 XOR a 6 LSH a 7 ASH a 8 ADD a 9 SUB a A JMP a B JMZ a C JMN a D CAL a E RET a F DEV i We could try the following: …. STO TMP ; save the integer LOA ZERO ; load zero SUB TMP ; subtract the integer …. TMP BSS 1 ZERO LIT 0 That’s quite a lot of code for such an operation, but TMP and ZERO can be shared, so we just write the three instructions everywhere we want to change the sign of an integer. And then we realize that sometimes this code does not work. Why? Better than Lego
0 HLT a 1 STO a 2 LOA a 3 AND a 4 OR a 5 XOR a 6 LSH a 7 ASH a 8 ADD a 9 SUB a A JMP a B JMZ a C JMN a D CAL a E RET a F DEV i We could try the following: …. STO TMP ; save the integer LOA ZERO ; load zero SUB TMP ; subtract the integer …. TMP BSS 1 ZERO LIT 0 That’s quite a lot of code for such an operation, but TMP and ZERO can be shared, so we just write the three instructions everywhere we want to change the sign of an integer. And then we realize that sometimes this code does not work: the range of integers is asymmetric! 0 – min_int = - min_int = min_int Better than Lego
0 HLT a 1 STO a 2 LOA a 3 AND a 4 OR a 5 XOR a 6 LSH a 7 ASH a 8 ADD a 9 SUB a A JMP a B JMZ a C JMN a D CAL a E RET a F DEV i We could try the following: …. STO TMP ; save the integer LOA ZERO ; load zero SUB TMP ; subtract the integer …. TMP BSS 1 ZERO LIT 0 That’s quite a lot of code for such an operation, but TMP and ZERO can be shared, so we just write the three instructions everywhere we want to change the sign of an integer. And then we realize that sometimes this code does not work: the range of integers is asymmetric! We take care not to change the sign of min_int, but in case we miss a case, we would like the machine to halt! Better than Lego
0 HLT a 1 STO a 2 LOA a 3 AND a 4 OR a 5 XOR a 6 LSH a 7 ASH a 8 ADD a 9 SUB a A JMP a B JMZ a C JMN a D CAL a E RET a F DEV i We take care not to change the sign of min_int, but in case we miss a case, we would like the machine to halt! …. STO TMP ; save the integer JMZ OK ; 0 != min_int LSH -1 ; shift out the sign bit JMZ ERR0 ; if zero left, it was min_int OKLOA ZERO ; load zero SUB TMP ; subtract the integer …. ERR0 HLT #FFFF ; halt in a visible manner TMP BSS 1 ZERO LIT 0 Better than Lego
0 HLT a 1 STO a 2 LOA a 3 AND a 4 OR a 5 XOR a 6 LSH a 7 ASH a 8 ADD a 9 SUB a A JMP a B JMZ a C JMN a D CAL a E RET a F DEV i We take care not to change the sign of min_int, but in case we miss a case, we would like the machine to halt! …. STO TMP ; save the integer JMZ OK ; 0 != min_int LSH -1 ; shift out the sign bit JMZ ERR0 ; if zero left, it was min_int OKLOA ZERO ; load zero SUB TMP ; subtract the integer …. ERR0 HLT #FFFF ; halt in a visible manner TMP BSS 1 ZERO LIT 0 So now we have even more code, and we must add three instructions everywhere we change the sign in our program! Better than Lego
0 HLT a 1 STO a 2 LOA a 3 AND a 4 OR a 5 XOR a 6 LSH a 7 ASH a 8 ADD a 9 SUB a A JMP a B JMZ a C JMN a D CAL a E RET a F DEV i We take care not to change the sign of min_int, but in case we miss a case, we would like the machine to halt! …. STO TMP ; save the integer JMZ OK ; 0 != min_int LSH -1 ; shift out the sign bit JMZ ERR0 ; if zero left, it was min_int OKLOA ZERO ; load zero SUB TMP ; subtract the integer …. ERR0 HLT #FFFF ; halt in a visible manner TMP BSS 1 ZERO LIT 0 So now we have even more code, and we must add three instructions everywhere we change the sign in our program! Actually, we must also generate a different label (e.g., OK0, OK1, OK2 …) every time we use this pattern. Better than Lego
0 HLT a 1 STO a 2 LOA a 3 AND a 4 OR a 5 XOR a 6 LSH a 7 ASH a 8 ADD a 9 SUB a A JMP a B JMZ a C JMN a D CAL a E RET a F DEV i We take care not to change the sign of min_int, but in case we miss a case, we would like the machine to halt! …. STO TMP ; save the integer JMZ OK ; 0 != min_int LSH -1 ; shift out the sign bit JMZ ERR0 ; if zero left, it was min_int OKLOA ZERO ; load zero SUB TMP ; subtract the integer …. ERR0 HLT #FFFF ; halt in a visible manner TMP BSS 1 ZERO LIT 0 So now we have even more code, and we must add three instructions everywhere we change the sign in our program! Surely, we can do better … Better than Lego
0 HLT a HALT the machine, after loading MA with a. 1 STO a STORE the accumulator: m[ a ] := A . 2 LOA a LOAD into the accumulator: A := m[ a ] . 3 AND a Bitwise AND: A := A bit_and m[ a ] . 4 OR a Bitwise OR: A := A bit_or m[ a ] . 5 XOR a Bitwise exclusive OR: A := A bit_xor m[ a ] . 6 LSH a Logical SHift(right if a positive, left otherwise) 7 ASH a Arithmetic Shift (with sign-extension) 8 ADD a ADD: A := A + m[ A ] 9 SUB a SUBTRACT: A := A – m[ A ] A JMP a JUMP: IC := a B JMZ a JUMP on Zero: if A = 0 then IC := a fi C JMN a JUMP on Negative: if A < 0 then IC := a fi D CAL a subroutine CALL: m[ a ] := IC; IC := a + 1 E RET a subroutine RETURN: IC := m[ a ] F DEV i DEVICE operation Better than Lego
D CAL a subroutine CALL: m[ a ] := IC; IC := a + 1 E RET a subroutine RETURN: IC := m[ a ] These two instructions allow us to “jump” to another fragment of code, and then jump back again. Better than Lego
D CAL a subroutine CALL: m[ a ] := IC; IC := a + 1 E RET a subroutine RETURN: IC := m[ a ] These two instructions allow us to “jump” to another fragment of code, and then jump back again. ….. 100: CAL 666 101: …. …. 375: CAL 666 376: …. …. 666: 0 667: …. …. 720:RET 666 Better than Lego
D CAL a subroutine CALL: m[ a ] := IC; IC := a + 1 E RET a subroutine RETURN: IC := m[ a ] These two instructions allow us to “jump” to another fragment of code, and then jump back again. ….. 100: CAL 666 101: …. …. 375: CAL 666 376: …. …. 666: 0 667: …. …. 720: RET 666 IC = 101 Better than Lego
D CAL a subroutine CALL: m[ a ] := IC; IC := a + 1 E RET a subroutine RETURN: IC := m[ a ] These two instructions allow us to “jump” to another fragment of code, and then jump back again. ….. 100: CAL 666 101: …. …. 375: CAL 666 376: …. …. 666: 101 667: …. …. 720: RET 666 IC = 101 Better than Lego
D CAL a subroutine CALL: m[ a ] := IC; IC := a + 1 E RET a subroutine RETURN: IC := m[ a ] These two instructions allow us to “jump” to another fragment of code, and then jump back again. ….. 100: CAL 666 101: …. …. 375: CAL 666 376: …. …. 666: 101 667: …. …. 720: RET 666 IC = 667 Better than Lego
D CAL a subroutine CALL: m[ a ] := IC; IC := a + 1 E RET a subroutine RETURN: IC := m[ a ] These two instructions allow us to “jump” to another fragment of code, and then jump back again. ….. 100: CAL 666 101: …. …. 375: CAL 666 376: …. …. 666: 101 667: …. …. 720: RET 666 IC = 668 Better than Lego
D CAL a subroutine CALL: m[ a ] := IC; IC := a + 1 E RET a subroutine RETURN: IC := m[ a ] These two instructions allow us to “jump” to another fragment of code, and then jump back again. ….. 100: CAL 666 101: …. …. 375: CAL 666 376: …. …. 666: 101 667: …. …. 720: RET 666 IC = 721 Better than Lego
D CAL a subroutine CALL: m[ a ] := IC; IC := a + 1 E RET a subroutine RETURN: IC := m[ a ] These two instructions allow us to “jump” to another fragment of code, and then jump back again. ….. 100: CAL 666 101: …. …. 375: CAL 666 376: …. …. 666: 101 667: …. …. 720: RET 666 IC = 101 Better than Lego
D CAL a subroutine CALL: m[ a ] := IC; IC := a + 1 E RET a subroutine RETURN: IC := m[ a ] These two instructions allow us to “jump” to another fragment of code, and then jump back again. ….. 100: CAL 666 101: …. …. 375: CAL 666 376: …. …. 666: 101 667: …. …. 720: RET 666 IC = 102 Better than Lego
D CAL a subroutine CALL: m[ a ] := IC; IC := a + 1 E RET a subroutine RETURN: IC := m[ a ] These two instructions allow us to “jump” to another fragment of code, and then jump back again. ….. 100: CAL 666 101: …. …. 375: CAL 666 376: …. …. 666: 101 667: …. …. 720: RET 666 IC = 376 Better than Lego
D CAL a subroutine CALL: m[ a ] := IC; IC := a + 1 E RET a subroutine RETURN: IC := m[ a ] These two instructions allow us to “jump” to another fragment of code, and then jump back again. ….. 100: CAL 666 101: …. …. 375: CAL 666 376: …. …. 666: 376 667: …. …. 720: RET 666 IC = 376 Better than Lego
D CAL a subroutine CALL: m[ a ] := IC; IC := a + 1 E RET a subroutine RETURN: IC := m[ a ] These two instructions allow us to “jump” to another fragment of code, and then jump back again. ….. 100: CAL 666 101: …. …. 375: CAL 666 376: …. …. 666: 376 667: …. …. 720: RET 666 IC = 667 Better than Lego
D CAL a subroutine CALL: m[ a ] := IC; IC := a + 1 E RET a subroutine RETURN: IC := m[ a ] These two instructions allow us to “jump” to another fragment of code, and then jump back again. ….. 100: CAL 666 101: …. …. 375: CAL 666 376: …. …. 666: 376 667: …. …. 720: RET 666 IC = 668 Better than Lego
D CAL a subroutine CALL: m[ a ] := IC; IC := a + 1 E RET a subroutine RETURN: IC := m[ a ] These two instructions allow us to “jump” to another fragment of code, and then jump back again. ….. 100: CAL 666 101: …. …. 375: CAL 666 376: …. …. 666: 376 667: …. …. 720: RET 666 IC = 721 Better than Lego
D CAL a subroutine CALL: m[ a ] := IC; IC := a + 1 E RET a subroutine RETURN: IC := m[ a ] These two instructions allow us to “jump” to another fragment of code, and then jump back again. ….. 100: CAL 666 101: …. …. 375: CAL 666 376: …. …. 666: 376 667: …. …. 720: RET 666 IC = 376 Better than Lego
D CAL a subroutine CALL: m[ a ] := IC; IC := a + 1 E RET a subroutine RETURN: IC := m[ a ] These two instructions allow us to “jump” to another fragment of code, and then jump back again. ….. 100: CAL 666 101: …. …. 375: CAL 666 376: …. …. 666: 376 667: …. …. 720: RET 666 IC = 377 Better than Lego
D CAL a subroutine CALL: m[ a ] := IC; IC := a + 1 E RET a subroutine RETURN: IC := m[ a ] These two instructions allow us to “jump” to another fragment of code, and then jump back again. ….. 100: CAL 666 101: …. …. 375: CAL 666 376: …. …. 666: 376 The contents of this word is sometimes called a trace . 667: …. …. 720: RET 666 IC = 377 Better than Lego
0 HLT a 1 STO a 2 LOA a 3 AND a 4 OR a 5 XOR a 6 LSH a 7 ASH a 8 ADD a 9 SUB a A JMP a B JMZ a C JMN a D CAL a E RET a F DEV i Back to our example: BSS 1 ; space for the argument MINUS BSS 1 ; entry point (space for trace) JMZ EXIT ; zero is its own negation STO MINUS – 1 ; save the argument LSH -1 ; shift out the sign bit JMZ ERR0 ; if zero left, it was min_int LOA ZERO ; load zero SUB MINUS – 1 ; subtract the argument EXIT RET MINUS ; return ; ERR0 HLT #FFFF ; halt in a visible manner TMP BSS 1 ZERO LIT 0 Better than Lego
0 HLT a 1 STO a 2 LOA a 3 AND a 4 OR a 5 XOR a 6 LSH a 7 ASH a 8 ADD a 9 SUB a A JMP a B JMZ a C JMN a D CAL a E RET a F DEV i Back to our example: BSS 1 ; space for the argument MINUS BSS 1 ; entry point (space for trace) JMZ EXIT ; zero is its own negation STO MINUS – 1 ; save the argument LSH -1 ; shift out the sign bit JMZ ERR0 ; if zero left, it was min_int LOA ZERO ; load zero SUB MINUS – 1 ; subtract the argument EXIT RET MINUS ; return ; ERR0 HLT #FFFF ; halt in a visible manner ZERO LIT 0 To change the sign of the integer in A we need only write: CAL MINUS Better than Lego
0 HLT a 1 STO a 2 LOA a 3 AND a 4 OR a 5 XOR a 6 LSH a 7 ASH a 8 ADD a 9 SUB a A JMP a B JMZ a C JMN a D CAL a E RET a F DEV i Back to our example: BSS 1 ; space for the argument MINUS BSS 1 ; entry point (space for trace) JMZ EXIT ; zero is its own negation STO MINUS – 1 ; save the argument LSH -1 ; shift out the sign bit JMZ ERR0 ; if zero left, it was min_int LOA ZERO ; load zero SUB MINUS – 1 ; subtract the argument EXIT RET MINUS ; return ; ERR0 HLT #FFFF ; halt in a visible manner ZERO LIT 0 To change the sign of the integer in A we need only write: CAL MINUS And so, we have effectively extended our machine with a new “instruction”. Better than Lego
CAL MINUS When we use a subroutine, we are said to call it, or to invoke it. A subroutine call is often called an “invocation”. Better than Lego
CAL MINUS When we use a subroutine, we are said to call it, or to invoke it. A subroutine call is often called an “invocation”. A subroutine is often called a procedure or a function, especially in the context of programming languages other than assembly language. Better than Lego