13 hours 15 minutes
Hello. This is Dr Miller in this is episode 14.8 of Assembly.
Today we're gonna talk about function, pointers,
So function pointer points to a function or a subroutine, as it sometimes is called.
And what this allows us to do is it allows us to change the functionality of a program at run time and so we can call different functions
based on that. And there are several different uses. So one is closures
or, um, curried functions. And so that's one example interrupt handlers or another.
And then if we have virtual functions inside of C plus plus or doing object or in programming design,
so in See this Intacs includes the arguments, and it includes the return type and the argument types. So each one of those is listed
so we can see that in a normal function declaration, we have our return type.
We then have our arguments. So we have a manager called X a double called B n a float called C.
And so we create a function pointer. We say the return type. So this returns a character, and then we just give the types of the arguments in here. So we have int double and float and we had to put those inside parentheses. So it knows those air part of that. And then here we give it a name and we say This is a pointer
to a function that takes an end, a double and afloat and returns a character.
And so that fund pointer is the name of the pointer that we're creating
for this function inside of C.
So once you've created a function pointer, you can use it just like any other function.
So I can have my fun
is the actual function returns a character and I can just use function pointer in the same type of Syntex.
Ah, we can also assign it value. So if we have a function pointer, weaken say are pointer is equal to the address of some function
um, and function be would have the same signature is the pointer that we defined, right? And so they have to be the same. Otherwise we'll get a compile a warning, saying that this function takes different arguments than what you've given it.
So let's look at some examples. So we have a couple of different functions here. We got print A and print. Be so they're defined right over here.
And you notice that print a prince eight times returns eight times a and print be returns eight times eight times a. So we got a squared and cubed.
And then when it does, the prince often says, Enter one foreign squared, enter to for and cubed And then here we're doing a choice. So here I've declared a function pointer.
So we got int pointer called print.
Um, it takes one imager as an argument, and then you can see I just use print as normal.
But inside of here, it either does choice one. It does print A as the function pointer or the address that it assigns to print and down here, print is then assigned to the address of print to be.
Then we go ahead and use our function as normal, and we print off the variable for that.
So here we can see that we have our print
ah, signing for print Eagle to print A and print B. And down here we can see the pointers are, um, moved into E B P minus 12.
And so we can see that it puts those offsets in there so it will do the calculation for us on the fly,
and then we can see at the end when it goes to call that function. So it moves that pointer into yea X and then doesnt call yea X. So that's one way we can tell that this is a function pointer as we're going to see a call to register instead of the normal function that we would normally see.
And so that's kind of giving us a hint that it's a function point. Or it's something that's dynamic, where the compiler cannot tell what it should use
for that function. So it's dynamic in nature.
So here's another example. And so we have a 32 bit function, and so here I just give that gave them into images that so I turned the address of this function into an imager. So I just figured out what that was. And this is 32 bit, and so an imager on 32 bit is the same as a pointer,
and so we're allowed to do that. And then what we do is we print off when we say Okay, here's the address of A and here's the address of B. We then read in a number from the user, so they're able to type one of their choices.
And then what we do is we declare a function pointer and we cast it
to the value that they typed in. So the user can actually type in a number, and that's the function that it's actually going to call.
And so here you can see a cast, which is wrapped around by parentheses. And then we got our return type, isn't This is gonna be a pointer, and it takes as an argument one imager pointer. So if this is a character than this would be a character right here.
And so then it gets gonna call that function
again, we're gonna print off the result to see what it is, and we have A and B again for the squared and cubed.
So when you run this, it'll basically print off addresses and your machine might give you completely different addresses. But here is that just for a and here is address for B. And so if I type in that number
and hit, enter it will read that imager and then it'll actually call that function
the same thing for be right, so B has a different value. I call that I end up with it running function be.
And so in our compiler, we can see that it's going to go ahead and it's going to, um, load those numbers into the variables we got at 14. And at 16 it's gonna load the addresses of our functions A and functions be
right. We're gonna go ahead and print those off so that the user knows what those are. So you can see that those get
push on the stack is arguments.
We can see the further down
that e V P minus 28 is gonna be our choice. And so then that
gets loaded into yea X right. And we then save it back into 20.
Ah, for our function, pointer. Right. So we're taking the value for choice and saving it into Fu, which is going to be right here, a 20.
And then when we go farther down, we'll see the call Tofu again. Here it's color coded and we can see it loads value from E V. P. Minus 20 so that variable called Fu gets loaded into yea X. And then we're gonna call the function yaks. So again, we're dynamically calling that function,
um, using a register because we don't know where it is.
So today we talked about function pointers in C, and we gave some different examples of how we can declare them and see and then use them within our C program in a valid way. And then we saw how that corresponded with our assembly code.
So in the next lecture, we'll talk about function pointers and will give an example in assembly and show how that works.
And then here's our quiz. So given the following sea function signature for Fred,
um, how would you create a function pointer for it?
So I gave it the name Ted. But you have character because that's our first type.
It's got a pointer. So put Prince sees around my pointer here, and then we have double and car. And so we pick all of the types out of it and use that as our function signature
to create our function Pointer.
If you have questions, you can email me Miller MJ at you and Kate I e to you. And you can find me on Twitter at Milhouse 30