13 hours 15 minutes
Hello. This is Dr Miller, and this is Episode 6.9 of Assembly.
Today we're gonna do is we're gonna write a function from scratch. And what we're gonna do is we're gonna use parameters.
The prologue and epilogue. We're going to save registers, and then we're gonna call some external functions.
So here's our problem to be solved. We want to write a program that prints out multiplication tables for the numbers one through nine, not including 10.
And we're going to read in the, um,
how many multiples we want to print. So, for example, if we type three,
then we'd print off for for the number of, say, five would print off 5 10 and 15. Or if we did four or 5 10 15 and 20.
And so we're gonna
we're going to start from the beginning and we will write an entire function and we'll do a minimal main program,
so I'll start off. I'm gonna define what my format string is for printing off the data. So
I'll just to find that first since, um, at the top of the file,
and we'll just put ah, we're gonna use print F.
So because we're going to use print if we need to define that as an external function,
And then in our main, we're just going to read a number. And we were gonna push it onto the stack because we're going to use parameters.
And then we got to correct the stack, so we'll call, read,
we will the value of that distort any X, So push X.
And then I'm gonna call my function printing. Um
And then I got to correct the stack so I could either add DSP or I could say,
um, pop e x Either one works.
So now we're gonna write our function, so I'll start off
and give our function of name, which have already said is, friend,
Now I'll start off with the prologue, So push E v p
movie B p E s p will come down here and define my epilogue.
And I'll put a label here
something to use that later saying where when I am, I done
so put in my epilogue, put in my return at the end and I've got my done label.
so we have our parameter on the stack and what we're gonna do is I'm gonna use E b X in order to
store what I'm incriminating stuff by. So
it was ebx is gonna count our our number, our initial numbers. Sorry.
And then we're gonna use E x
for the multiple to print, and I must start dot off at one.
And then I'm gonna use e d. X
as the number that I need to add. And I'm gonna start off zero because I want to increment it inside of my initialization.
So in my initialization,
what I want to do is I want to incriminate GDX. So each time through, I wanted to be one higher than what it was before.
And then I want to use e c x for my loop. So easy X is going to say, How many times am I going to go and print off this number? So it might be, you know, four or 5 10 what have you So I'll use E c x for that,
and then I'm using any BP based stack. So if you recall,
PBP plus eight is our first parameter, So that should be the parameter that is up here that's getting pushed onto the stack, right, Because we used our standard prologue.
And then here I'm going to,
um, copy into yea x
the value of e d. X. And so that's going to write. GDX is gonna increment each time, and it's going to say what I'm gonna add to it. And so then each time through it will be the next number in my loop
and then we'll copy that back. So we've implemented E. D. X copied the incremental version two yea x and then copied that back ttx just to be safe.
All right, and then inside of here, we want to be able to
print off our number, so to print our number.
So the number we're gonna print is going to be any X. So I'm gonna push
push my format that I want to print, which I defined at the top
call print and F
And then I gotta fix the stack because I to push two parameters on. I need to fix those. And so we'll go ahead and
add to yes, p
eight Mary, because four for each one of those
soon I'll call print F
and then when I'm all done right
each time through my loop
I want to,
to be a X, the value that's a needy ex. So if I'm counting my fives, e d x will have five and e x will have five the first time in in 10 and 15 and then 20 and 25.
each time through here, I want to loop back up to, um,
the top, and this is where I'm going to print it again. So it's a loop,
and then I'll define a variable crop top. And so that's where I'm going to go in print,
so this will print off. So if we have the number one, it's gonna print off 12345 If five is our maximum,
and then what we want to do is we want to go now and do 2468 10
for our example. So we're gonna have another loop, right? So we can't use to loop constructs. We would have to actually implement incremental it ourselves.
And so to do that, we're using EBX. So ebx is our number that we want to do, so we'll go ahead and increment
e B X
and then compare
E v X to the number, say 10. So I'm using 10. We can we're gonna go up to, but not including 10 in this example. But you could change it
to meet your needs.
And then each time through, I will want to print a new lines that I know that I'm done with, say, the multiples of one, then the multiples of two and in multiples of three.
So go ahead and call print
So I've done my comparison to EBX and 10 and so I can say jump. Not if it's not zero. Then I
I went to go back up to the and yet part,
and that's why I set up in it the way I did. Right? So it does some,
um you know, incremental GDX. So the first time through e. D. X was one because I incremental from zero.
So now it should go to two and then a copy to Ta X and then should Sylvia needy ex
and then we go through in print off right. Adding the number two each time Ta x, which again is set to to
that should be the entirety of the part that we need in order to get stuff done.
Looks like I didn't have any syntax airs.
So if I want to print my multiples of five,
we end up with a problem.
And so the problem is that inside of
the print of function, it actually destroys values for E x e d X and E C X.
So print F is messing up our variables that we're using a for the looping and be for our numbers, right, because the return result of a function
is whether or not it was successful or the value that it needed.
And so this is messing up all of our variables. And so what we need to do is we need to save our our registers
that we are using. So in our function, we're using a X e b x,
yeah, ebx ccx and Edie X. So I can go ahead and save all of those
before I call print F. So here I am,
calling print F,
And then I've got some work that I'm doing down here.
So I want to restore my registers,
so you should think about What is the order that I need to restore my registers?
All right, so all do it. So we're gonna do pop GDX
pop E C X
pop E b X
pop e X. Right. So now I have restored all of my registers from the previous values that they had,
right? And they're saved on the stack. So now when print up messes with my function
right, it won't actually hurt my registers.
So I typed five for my number and so right, The first loop. It's using one as my what? I'm gonna increment by. So I go. 12345
And now in our function, right e d X becomes too. And so that's what I'm incremental by. So I got to for 68 10
and then 369 12 15 doing each multiple up to, but not including the number 10.
And then if I enter the number 10 right, so I print off 10 multiples of each one of these numbers.
Now, one of the things that we also talked about was saving all the registers that you use so that you don't mess them up.
So again we could save our registers. So we used yea x e b x e c x and e d x
So I'll pick a random order,
right? So I did e c x then ea accident GDX than ebx.
So at the end of my function,
if I can get down here
now, my order is gonna kill me here. So let's look
b and n d
be an Indy and then a and then see
so I just have to make sure that I know what the order was before I called the function and what the order is after
and what we can do is we can see if we did it right. So we're getting ready. We're calling our function
so we can
dump our registers
before and after,
so I'll just do to
so we can see.
But you could pick a different number.
So again, see a X e x is two nuggets restored ebx zero before zero after
e c x
looks like ff 988 f d zero
Same thing there
and then here FF
98 ff four on that is also restored so we can see that we didn't modify anything right because we went through and made sure that all of the registered that were using in our function we saved
before we modified them. And then when we got to the end, we restored the values back to the where they were.
We used our function prologue and and here's our epilogue.
We used our prologue at the very beginning,
right? And then
we had to fix the air when the fact that another function had obliterated our registers, we needed it to save them and restore them before and after it obliterated them because we wanted to get back to the previous state that we're at.
We also used one parameter.
All right, so e v P plus eight was our parameter. And we use that in order to determine how many times that we were going to do our
our inner loop.
So today we looked at creating a function from the very beginning, using the conventions that we've talked about in previous lectures.
And then we ran into a problem and we had to understand what is the way that I can solve it? And why is it a problem? Why is it a problem that functions,
Um, obliterate registers. And how do you fix that problem?
Next time we're going to talk about a recursive function or a function that calls itself.
And if you have questions, you can contact me at Miller MJ at you and Kate. I e do you can find me on Twitter at Milhouse 30.