字幕列表 影片播放 列印英文字幕 >> Sean: We've done a series of hardware videos with Dr Bagley about various different parts of CPUs, and things like this. And one of the things he'd mentioned during one of the videos is something that I believe you want to tell us a bit more about -- the Wheeler Jump ? >> DFB: Yes the Wheeler Jump David Wheeler [a] very very talented computer scientist. An excellent lateral thinker. I didn't know him very well; I knew him very slightly. Maybe met him four or five times but you just had to be impressed that he, as a computer pioneer, had to grapple with the fact that very early computers did not have enough registers in their CPUs. >> Sean: Registers are just like tiny bits of memory? >> DFB: Yeah! tiny bits of memory, but within the central processor unit. They could be built of much faster technology than main memory, so typically, you know, like with the ARM chip at user level, you'd end up with 16 general-purpose registers. One or two of those might be set aside to use for all sorts of useful things. And one of the useful things was the idea of -- you're running through your program -- you want to jump into a subroutine to calculate a sine, or to print out "Hello World", or something like that. You don't want it to be running linearly on your program you want to jump into it and jump back out of it again. So you could use it several times in your program from several different places. You could jump in and jump back out. Now David Wheeler is credited with this idea of inventing the subroutine and say[ing] "Well, yeah, when people want to calculate sine of something they don't want to have to replicate, in their program, the coding for sine in six different places". It might make it go faster - and of course some of you will know that if you write macros you can force it [to create in-line code] to do that. [You] sacrifice a lot more code for faster speed But no, to keep it clean you basically say "I want this piece of code to be separate but "jumpable into" and "jump back outable from", back to where you came from. So, before you jump in, at the moment of the jump, you've got to say "Where am i coming from? Whose responsibility is it to remember that? And in modern CPUs you would have a link register of some sort that remembers. You didn't have that in the very early days. But, boy, did it [soon] dawn on them that you needed it! So if you didn't have a link register how on earth were you going to get into, and out of, your subroutine? So let's say you're coming from 70 shall we say - location 70 - something like that? Right, now, on this particular occasion therefore - when you get back out of that subroutine - you don't want to go back to 70 itself because you'd end up in an endless loop of jumping back into yourself you want to go to the instruction just beyond 70. But you want to get back out! You want to remember 70 [and] add -- depending on the architecture -- you add 1, 2, 4 ... depending. whetherWhen it's a byte machine, a word machine, whatever. But you add a small number on to that address and say: "That's where I want to get back to -- the instruction after where I jumped from". >> Sean: And the problem is that you've got nowhere tosave [it]? >> DFB: Well, on modern machines [address] 70 would be saved in a link register, maybe [on the ARM chip] register number 14, or something. You say: "Jump to subroutine". The moment you say it, it automatically remembers where you're jumping from and puts it in the link register. So when you want to come back out you say: "ere I am, on this architecture, where's my link register? Number 14?. Let's look at its content. Oh! it says "70" and I'm on a 32-bit machine with 4 bytes to the word so that's ... I want to jump 4 beyond 70". Or if it's, y' know, like EDSAC it might be 1 or 2 beyond. But you want to just jump back to where you came from, slightly adjusted, with a little amount added. And it is that link register that saves you from going insane. Now back in the early days of David Wheeler and this EDSAC machine he had to do this for ... Oh golly! I wish I had an extra register but I haven't Wat register have I got, that's in use all the time, that might - if I'm very careful - serve me all right. And the answer is - the Arithmetic Accumulator. Every time you loaded a number into the accumulator, or did some arithmetic, the answer stays in the accumulator. OK, so here's the deal: we're going to use the arithmetic accumulator as the means of remembering where we came from. So here you are at location 70, in the early EDSAC machine, what do you have to do ... >> Sean: So, you have to add 70 to 0, or something? >> DFB: Yes! Basically "yes"! You're jumping from 70 -- OK 70 has got to be in the accumulator at the moment of jump -- and then you do an unconditional branch instruction to get to the start of the subroutine. Fine! But you wake up in that subroutine your first job is to preserve your link to get back! You must NOT do any arithmetic - because you [might] feel like it. Duty calls! You must save off your return link somewhere safe! Right?! Because, if you don't, you won't be able to get back. But you have no spare ... >> Sean: So we've got nowhere to save .... >> DFB: ... no spare registers to save it Yeah! you might think so, but how about this: suppose at the bottom of your subroutine there is a branch instruction, a dummy one, which is basically going to say branch, or jump, back to where I came from. But "where I came from" must be a literal correct address. And in the accumulator is 70. So what you that have to do is - knowing the length of your subroutine and its addresses and knowing where the return instruction is planted as a dummy - you've basically got to turn 70 into 72, 74, whatever it is, to make it go back to the next instruction after where you came from. And you must literally plant that instruction and - shock! horror! - overwrite your own program code at the bottom of this subroutine, so that the dummy jump, which has probably got zeros left in it by now, becomes jump back to location 72, shall we say. But you are actually altering memory. Now can you imagine if that goes wrong, how to debug a program that's trampling all over itself and jumping back to the wrong address! you know >> Sean: Code gets altered all the time, right?! Can you give us some sense of how sacrosanct these lines of code are when it's running? >> DFB: Well, code may seem to alter itself all the time but it's usually altering itself by manipulating registers in the CPU not physically overwriting memory in your main memory store. >> Sean: So it's OK to obviously change the value for variables, and and all of that, but actually changing those lines of code should be .... >> DFB: Changing variables is fine. That's data. You're allowed to change data. What you're not allowed to do is to treat a program-instruction bit pattern as if it was just a piece of data and to patch something on top of it Now you can do this on Z80 chips, I've tried doing it! If you go to very simple chips there's no protection mechanisms. They'll let you do anything you want and you just hang yourself! Fine. More advanced chips, now, and particularly operating systems make use of this, give you an ability to mark which pieces of memory are read-only and are not to be overwritten. And that way you can stay fairly sane. Although you've left behind a polluted piece of code saying "jump back to 72" the next time you come into this routine - maybe having jumped from 256, shall we say, you've now got to remember 256six in the accumulator. The moment you get in there you adjust it ever so slightly to come back to 258, or whatever it is, and you plant that instruction to overwrite the jump back to 72 which is still there, literally inside your code. So, every single call you make into that subroutine the link back has to overwrite whatever usage you had before and plant it in exactly the right place to get back. You can see now why the moment EDSAC II came along - all of a sudden this had link registers. All of this early experience just showed the pioneers what the next generation of machinery had to have. And that's how the importance of link registers became obvious. It will have occured to you of course, Sean, I think I've got this right, that doing it the day David Wheeler way with a Wheeler Junp, right, you successively at the end of your routine of writing back and patching it with your address you need to get back to, That's fine and it'll work. But what does that NOT enable you to do? Begins with an "R". omen >> Sean: A further ... recursion oh yeah! >> DFB: One of thereasons for wanting a more general mechanism for doing it is [that] you can't do recursion with the Wheeler method because you've only got one place in memory, at the end of the subroutine, where you patch back a new return address. What you need with recursion is to have *several* return addresses all waiting to be used queued up ... no not queued up ... stacked up on tha stack. So, that's the other thing. >> Sean: Recursion is obviously a very particular special case but does this Wheeler Jump not even allow you to do branches in branches? >> DFB: Oh! you can do that. Yes, yes, you can do that but but actually having, y'know a thing call itself, since you've textually only got one copy of the routine, just one, you're not able to replicate the text in any way, there's no ability to do that. You can only damage that one return address, just the one. That means that the next realization from being a pioneer is my golly we've gotta be able to do recursion. My golly we need more general-purpose registers and all this kind of stuff. And oh! also, wouldn't it be nice to put a marker on memory saying: "Don't let anybody over-write this!" And actually have it hardware- imposed not just by people's good nature.
B1 中級 Wheeler Jump - Computerphile (Wheeler Jump - Computerphile) 6 0 林宜悉 發佈於 2021 年 01 月 14 日 更多分享 分享 收藏 回報 影片單字