Hello. This is Dr Miller and this is Episode 6.4 of Assembly.
Today we're gonna talk about creating a function and then running into bugger on that function,
so creating functions.
So to define a function, we basically need two things. The first thing is a label, and that is the name of the function
and then a return at the end.
And then in order to execute the function, we use the call instruction.
So call says that we're going to start executing a function. What it's going to do is it's gonna push the return address of the next instruction on to the top of the stack,
and then it's going to start executing that function. So to do that, it jumps to the address of the function. And then e i. P is set to that function address. And that's how it starts executing Z e. I. P always points to our current instruction,
and then, when the function is all done, will issue the return instruction,
and so that will pop off the address that's on the top of the stack and set E I p to it and then continue so you can see
this will save that next instruction that we want to execute. And then this will restore it when we are all done.
And today we're gonna do a little bit of debugging just so that we can see exactly how the system works. So exactly how the stack is related to the function and the current instruction is going to be executed.
So I think that the GEF or Jeff type of a framework for G B is really nice.
And so if you Google g f, you will find it. Here is a link to the get help page and then on their page,
they have how you can execute a script to just install it by default.
And so this is the command that I ran inside of my terminal in order to get it installed. And so once you do that, then you can continue.
So today we're going to create a simple function.
And so the function is called Cleary X. All it does is moved zero into E X and then return.
So you see that we have a label here that has a name and then a colon, and then we have this is the body of our function. Move zero yea x And then we're gonna do return
and then inside of our main, we're going to call this function,
and then when we're all done, we'll go ahead and
we can print off registers. And I have a couple different examples that will go through.
So let's get that started.
So go ahead and ended our file,
and what we're gonna do here is we're gonna put a few commands in in order to help us visualize the stack. So I'm gonna copy a couple things and push them onto the stag.
So I moved feed beef into yea X, and then I'll go ahead and push that on top of the stack on the move
push that onto this top of the stack
and then I'm going to end up calling my function. So
that's the name of my function.
Now, if we notice inside of my program right, I actually have already a function right. A sm underscore main.
That's the name of our function. And at the end, it has a return.
We'll talk about enter and leave later on. But that's a function right. So generally what you want to do is you want to have a function, start and then end, and then you define additional functions. So I'm gonna come down here and define my function.
So I have a label which is a string followed by a colon, and then do what I want to do a movie, a x zero,
and I'll do your return.
And then if we recall from previous lectures, right, I pushed to things on to the top of the stack, and so I need to clear off the stack here
I have four for each one of these. And so four times two is eight. So I have to add a TSP.
All right, so now we should be ready.
And when we run it, it's not going to do anything. Um,
but that's okay, right? We're gonna run it into the bugger. So we're going to see exactly how this works
so that the bugger is called the canoe to bugger or GTB. So go ahead and execute that G D B. And then we give it the name of the program that we went to the bug and so this example is six point for
if you've run the gifts script that I put in the previous one, you'll see ah g e f here in an arrow pointer.
And so here we can run a couple different commands. So probably the simplest one is to set a break point. So be is to set a break point. And the function that I want to set a break point is a sm underscore
Maine, and that is our main function. We can see it has a label. We could also put one EDT in the clear the a X.
That's also a function.
So now that we've set break points, we can start running our program.
This is where more gift really works. Well, so if I type are in order to run
now, we're going to see in here and the reason I made my terminal so small it's that we can get all of this stuff on the screen.
So if we see up here, we can see that we have registers. So this is showing us what all of the registers that we have inside of our program. So we got ta x e c x e x e s p e b p s i e d i e i p and then our flags
so we can see all of our registers, as they currently are. We can see the stack.
So on the stack you will see the very top is what's pointed to by E. S. P. And so, as we push things, you'll see stuff move down the stack
and then we can see the code. So this is where where exactly were running. And so we're at a sm Maine, and it stopped at S a main plus four. So this is the next instruction that's going to get executed when we execute this function,
and we've got a couple of different commands. So we've got step instruction and next in stuck construction,
so s I, or step instruction means do the next instruction.
And if there's a function call, go into that function call, whereas next instruction will
step into that. And so we'll see the difference here in a little bit.
So I'm just going to use step instruction
to see each one of these. And if I hit enter, it'll do the previous come in. So I'm just going to step each instruction.
So here we can see we got movie a X and then feed beef.
And so we should ce exchange here when we execute that command.
So now we can see that Yea x is feed beef.
And so now it's going to do a pushy a X.
So you should see the X should go on top of the stack,
right? And so now we can see E S P is pointing to feed beef. So now eat that feed. Beef is on top of the stack.
Now here, we're gonna copy beef beef into E X.
So now, yea X has beef beef. And now this should get copy to the top of the stack and then feed beef will move down.
so now if I did at this point, right, we've put on those two items on top of our stack, and then we're ready to call our function,
and we can see the that GEF is trying to show us what our function look like. Normally, a function has more than just to instructions.
This one only has to. So we're only going to see these And then this stuff here is going to be garbage. That is not really instructions, because the return is gonna exit from that.
And so here, if I did next instruction, it would step over that call. We wouldn't get to see what happens. But we're going to use step instruction or go to the next one. And if it's a call, go into that call function.
So we're going to see the return address. So the address of the next instruction. So after a Assam underscore Main plus 17 the next instruction is going to get executed and I can scroll up.
We should be able to see the next instruction. Is this one right? Here it is. The ad E s p eight
and its value is 80 48
four c six. So that is the value that's going to get push on set because that's the next instruction that we want to execute from what we're at right now.
So I'll go ahead and do step instruction. We should see
that we will enter this function, and then that return address is gonna get pushed on top of the stack.
So now if we look, we can see that that number that I just said earlier is pushed on top of the stack and there's an extra zero because it's gotta fill all eight bits.
And so now we're in our function. Our function is going to move zero in T A X, and then it's going to return. And so it's gonna pop this off of the stack, and then we will be running that other instruction. So right now we're in the function
that shows here, clear E X,
so I'll go ahead and step.
yea, X has got set to zero because that's what our function is going to do. At this point, we're ready to do our return. So we're gonna go back to our ace in Maine. We're gonna go back to this address right here, so this will get popped off of the stack.
So now we can see yea x zero, which is what you are. We wanted our function to do,
and again, the top of the stack is beef, beef and then feed beef right in the reverse order that we pushed them on.
And so now if we step,
we can see that those disappeared because we added our 80 s p and now E S p points to where it originally appointed. When are functioning started.
And so we ended up with the result of yea ex being zero, which is what we wanted to do inside of our function, right? We had moved other values in there,
and so now we're all done. So for all done, we can hit C to continue, and it'll continue running the program until it exits
and says the program exited normally.
so today we talked about creating a function and then using our to bugger on the function so we could kind of understand what happens when you call a function. What happens to the stack? What gets added to the stack when you do a call instruction and what happens when you do a return instruction?
So, looking forward, we're gonna look Atmore complicated functions. All right, so we're gonna add some
parameters to it. We're going to also talk about how do we save registers, so that way they don't get clobbered,
and then we'll talk about recursive functions.
If you have questions, you can email me at Miller MJ at you and Kate I e to you, and you can find me on Twitter at Milhouse 30