Advertisement
Guest User

Untitled

a guest
Oct 14th, 2019
66
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 11.85 KB | None | 0 0
  1. Hi, I’m Carrie Anne and this is Crash Course Computer Science!
  2. 0:06
  3. Last episode, we combined an ALU, control unit, some memory, and a clock together to
  4. 0:10
  5. make a basic, but functional Central Processing Unit – or CPU – the beating, ticking heart
  6. 0:14
  7. of a computer.
  8. 0:15
  9. We’ve done all the hard work of building many of these components from the electronic
  10. 0:19
  11. circuits up, and now it’s time to give our CPU some actual instructions to process!
  12. 0:23
  13. The thing that makes a CPU powerful is the fact that it is programmable – if you write
  14. 0:28
  15. a different sequence of instructions, then the CPU will perform a different task.
  16. 0:31
  17. So the CPU is a piece of hardware which is controlled by easy-to-modify software!
  18. 0:36
  19. INTRO
  20. 0:44
  21. Let’s quickly revisit the simple program that we stepped through last episode.
  22. 0:48
  23. The computer memory looked like this.
  24. 0:50
  25. Each address contained 8 bits of data.
  26. 0:52
  27. For our hypothetical CPU, the first four bits specified the operation code, or opcode, and
  28. 0:57
  29. the second set of four bits specified an address or registers.
  30. 1:00
  31. In memory address zero we have 0010 1110.
  32. 1:04
  33. Again, those first four bits are our opcode which corresponds to a “LOAD_A” instruction.
  34. 1:10
  35. This instruction reads data from a location of memory specified in those last four bits
  36. 1:14
  37. of the instruction and saves it into Register A. In this case, 1110, or 14 in decimal.
  38. 1:21
  39. So let’s not think of this of memory address 0 as “0010 1110”, but rather as the instruction
  40. 1:27
  41. “LOAD_A 14”.
  42. 1:28
  43. That’s much easier to read and understand!
  44. 1:30
  45. And for me to say!
  46. 1:31
  47. And we can do the same thing for the rest of the data in memory.
  48. 1:35
  49. In this case, our program is just four instructions long, and we’ve put some numbers into memory
  50. 1:39
  51. too, 3 and 14.
  52. 1:41
  53. So now let’s step through this program:
  54. 1:42
  55. First is LOAD_A 14, which takes the value in address 14, which is the number 3, and
  56. 1:47
  57. stores it into Register A.
  58. 1:49
  59. Then we have a “LOAD_B 15” instruction, which takes the value in memory location 15,
  60. 1:54
  61. which is the number 14, and saves it into Register B.
  62. 1:56
  63. Okay.
  64. 1:57
  65. Easy enough.
  66. 1:58
  67. But now we have an “ADD” instruction.
  68. 2:00
  69. This tells the processor to use the ALU to add two registers together, in this case,
  70. 2:04
  71. B and A are specified.
  72. 2:06
  73. The ordering is important, because the resulting sum is saved into the second register that’s specified.
  74. 2:11
  75. So in this case, the resulting sum is saved into Register A.
  76. 2:15
  77. And finally, our last instruction is “STORE_A 13”, which instructs the CPU to write whatever
  78. 2:19
  79. value is in Register A into memory location 13.
  80. 2:23
  81. Yesss!
  82. 2:24
  83. Our program adds two numbers together.
  84. 2:26
  85. That’s about as exciting as it gets when we only have four instructions to play with.
  86. 2:30
  87. So let’s add some more!
  88. 2:31
  89. Now we’ve got a subtract function, which like ADD, specifies two registers to operate on.
  90. 2:35
  91. We’ve also got a fancy new instruction called JUMP.
  92. 2:38
  93. As the name implies, this causes the program to “jump” to a new location.
  94. 2:42
  95. This is useful if we want to change the order of instructions, or choose to skip some instructions.
  96. 2:45
  97. For example, a JUMP 0, would cause the program to go back to the beginning.
  98. 2:48
  99. At a low level, this is done by writing the value specified in the last four bits into
  100. 2:53
  101. the instruction address register, overwriting the current value.
  102. 2:56
  103. We’ve also added a special version of JUMP called JUMP_NEGATIVE.
  104. 3:00
  105. This only jumps the program if the ALU’s negative flag is set to true.
  106. 3:04
  107. As we talked about in Episode 5, the negative flag is only set when the result of an arithmetic
  108. 3:08
  109. operation is negative.
  110. 3:10
  111. If the result of the arithmetic was zero or positive, the negative flag would not be set.
  112. 3:14
  113. So the JUMP NEGATIVE won’t jump anywhere, and the CPU will just continue on to the next instruction.
  114. 3:19
  115. And finally, computers need to be told when to stop processing, so we need a HALT instruction.
  116. 3:24
  117. Our previous program really should have looked like this to be correct, otherwise the CPU
  118. 3:28
  119. would have just continued on after the STORE instruction, processing all those 0’s.
  120. 3:32
  121. But there is no instruction with an opcode of 0, and so the computer would have crashed!
  122. 3:36
  123. It’s important to point out here that we’re storing both instructions and data in the
  124. 3:40
  125. same memory.
  126. 3:41
  127. There is no difference fundamentally -- it’s all just binary numbers.
  128. 3:43
  129. So the HALT instruction is really important because it allows us to separate the two.
  130. 3:47
  131. Okay, so let’s make our program a bit more interesting, by adding a JUMP.
  132. 3:51
  133. We’ll also modify our two starting values in memory to 1 and 1.
  134. 3:55
  135. Lets step through this program just as our CPU would.
  136. 3:58
  137. First, LOAD_A 14 loads the value 1 into Register A.
  138. 4:01
  139. Next, LOAD_B 15 loads the value 1 into Register B.
  140. 4:05
  141. As before, we ADD registers B and A together, with the sum going into Register A. 1+1 = 2,
  142. 4:11
  143. so now Register A has the value 2 in it (stored in binary of course)
  144. 4:15
  145. Then the STORE instruction saves that into memory location 13.
  146. 4:18
  147. Now we hit a “JUMP 2” instruction.
  148. 4:20
  149. This causes the processor to overwrite the value in the instruction address register,
  150. 4:24
  151. which is currently 4, with the new value, 2.
  152. 4:27
  153. Now, on the processor’s next fetch cycle, we don’t fetch HALT, instead we fetch the
  154. 4:31
  155. instruction at memory location 2, which is ADD B A.
  156. 4:34
  157. We’ve jumped!
  158. 4:35
  159. Register A contains the value 2, and register B contains the value 1.
  160. 4:38
  161. So 1+2 = 3, so now Register A has the value 3.
  162. 4:42
  163. We store that into memory.
  164. 4:44
  165. And we’ve hit the JUMP again, back to ADD B A.
  166. 4:47
  167. 1+3 = 4.
  168. 4:49
  169. So now register A has the value 4.
  170. 4:51
  171. See what's happening here?
  172. 4:52
  173. Every loop, we’re adding one.
  174. 4:53
  175. Its counting up!
  176. 4:54
  177. Cooooool.
  178. 4:55
  179. But notice there’s no way to ever escape.
  180. 4:57
  181. We’re never.. ever.. going to get to that halt instruction, because we’re always going
  182. 5:01
  183. to hit that JUMP.
  184. 5:02
  185. This is called an infinite loop – a program that runs forever… ever… ever… ever…
  186. 5:07
  187. ever
  188. 5:08
  189. To break the loop, we need a conditional jump.
  190. 5:10
  191. A jump that only happens if a certain condition is met.
  192. 5:13
  193. Our JUMP_NEGATIVE is one example of a conditional jump, but computers have other types too - like
  194. 5:18
  195. JUMP IF EQUAL and JUMP IF GREATER.
  196. 5:20
  197. So let’s make our code a little fancier and step through it.
  198. 5:24
  199. Just like before, the program starts by loading values from memory into registers A and B.
  200. 5:28
  201. In this example, the number 11 gets loaded into Register A, and 5 gets loaded into Register B.
  202. 5:34
  203. Now we subtract register B from register A. That’s 11 minus 5, which is 6, and so 6
  204. 5:39
  205. gets saved into Register A.
  206. 5:40
  207. Now we hit our JUMP NEGATIVE.
  208. 5:42
  209. The last ALU result was 6.
  210. 5:44
  211. That’s a positive number, so the the negative flag is false.
  212. 5:47
  213. That means the processor does not jump.
  214. 5:49
  215. So we continue on to the next instruction...
  216. 5:51
  217. ...which is a JUMP 2.
  218. 5:52
  219. No conditional on this one, so we jump to instruction 2 no matter what.
  220. 5:56
  221. Ok, so we’re back at our SUBTRACT Register B from Register A. 6 minus 5 equals 1.
  222. 6:01
  223. So 1 gets saved into register A.
  224. 6:03
  225. Next instruction.
  226. 6:04
  227. We’re back again at our JUMP NEGATIVE.
  228. 6:06
  229. 1 is also a positive number, so the CPU continues on to the JUMP 2, looping back around again
  230. 6:11
  231. to the SUBTRACT instruction.
  232. 6:13
  233. This time is different though.
  234. 6:14
  235. 1 minus 5 is negative 4.
  236. 6:17
  237. And so the ALU sets its negative flag to true for the first time.
  238. 6:20
  239. Now, when we advance to the next instruction,
  240. 6:23
  241. JUMP_NEGATIVE 5, the CPU executes the jump to memory location 5.
  242. 6:27
  243. We’re out of the infinite loop!
  244. 6:29
  245. Now we have a ADD B to A. Negative 4 plus 5, is positive 1, and we save that into Register A.
  246. 6:35
  247. Next we have a STORE instruction that saves Register A into memory address 13.
  248. 6:39
  249. Lastly, we hit our HALT instruction and the computer rests.
  250. 6:43
  251. So even though this program is only 7 instructions long, the CPU ended up executing 13 instructions,
  252. 6:49
  253. and that's because it looped twice internally.
  254. 6:52
  255. This code calculated the remainder if we divide 5 into 11, which is one.
  256. 6:56
  257. With a few extra lines of code, we could also keep track of how many loops we did, the count
  258. 7:00
  259. of which would be how many times 5 went into 11… we did two loops, so that means 5 goes
  260. 7:05
  261. into 11 two times... with a remainder of 1.
  262. 7:08
  263. And of course this code could work for any two numbers, which we can just change in memory
  264. 7:12
  265. to whatever we want: 7 and 81, 18 and 54, it doesn’t matter -- that’s the power
  266. 7:17
  267. of software!
  268. 7:18
  269. Software also allowed us to do something our hardware could not.
  270. 7:21
  271. Remember, our ALU didn’t have the functionality to divide two numbers, instead it’s the
  272. 7:26
  273. program we made that gave us that functionality.
  274. 7:28
  275. And then other programs can use our divide program to do even fancier things.
  276. 7:32
  277. And you know what that means.
  278. 7:34
  279. New levels of abstraction!
  280. 7:41
  281. So, our hypothetical CPU is very basic – all of its instructions are 8 bits long, with
  282. 7:46
  283. the opcode occupying only the first four bits.
  284. 7:49
  285. So even if we used every combination of 4 bits, our CPU would only be able to support
  286. 7:54
  287. a maximum of 16 different instructions.
  288. 7:56
  289. On top of that, several of our instructions used the last 4 bits to specify a memory location.
  290. 8:01
  291. But again, 4 bits can only encode 16 different values, meaning we can address a maximum of
  292. 8:06
  293. 16 memory locations - that’s not a lot to work with.
  294. 8:10
  295. For example, we couldn’t even JUMP to location 17, because we literally can’t fit the number
  296. 8:15
  297. 17 into 4 bits.
  298. 8:16
  299. For this reason, real, modern CPUs use two strategies.
  300. 8:19
  301. The most straightforward approach is just to have bigger instructions, with more bits,
  302. 8:23
  303. like 32 or 64 bits.
  304. 8:25
  305. This is called the instruction length.
  306. 8:28
  307. Unsurprisingly.
  308. 8:29
  309. The second approach is to use variable length instructions.
  310. 8:32
  311. For example, imagine a CPU that uses 8 bit opcodes.
  312. 8:35
  313. When the CPU sees an instruction that needs no extra values, like the HALT instruction,
  314. 8:40
  315. it can just execute it immediately.
  316. 8:41
  317. However, if it sees something like a JUMP instruction, it knows it must also fetch
  318. 8:45
  319. the address to jump to, which is saved immediately behind the JUMP instruction in memory.
  320. 8:50
  321. This is called, logically enough, an Immediate Value.
  322. 8:52
  323. In such processor designs, instructions can be any number of bytes long, which makes the
  324. 8:56
  325. fetch cycle of the CPU a tad more complicated.
  326. 8:59
  327. Now, our example CPU and instruction set is hypothetical, designed to illustrate key working
  328. 9:04
  329. principles.
  330. 9:05
  331. So I want to leave you with a real CPU example.
  332. 9:07
  333. In 1971, Intel released the 4004 processor.
  334. 9:11
  335. It was the first CPU put all into a single chip and paved the path to the intel processors
  336. 9:15
  337. we know and love today.
  338. 9:17
  339. It supported 46 instructions, shown here.
  340. 9:19
  341. Which was enough to build an entire working computer.
  342. 9:22
  343. And it used many of the instructions we’ve talked about like JUMP ADD SUBTRACT and LOAD.
  344. 9:26
  345. It also uses 8-bit immediate values, like we just talked about, for things like JUMPs,
  346. 9:31
  347. in order to address more memory.
  348. 9:33
  349. And processors have come a long way since 1971.
  350. 9:36
  351. A modern computer processor, like an Intel Core i7, has thousands of different instructions
  352. 9:41
  353. and instruction variants, ranging from one to fifteen bytes long.
  354. 9:44
  355. For example, there’s over a dozens different opcodes just for variants of ADD!
  356. 9:48
  357. And this huge growth in instruction set size is due in large part to extra bells and whistles
  358. 9:52
  359. that have been added to processor designs overtime, which we’ll talk about next episode.
  360. 9:57
  361. See you next week!
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement