Hello, this is Dr. Miller, and this
is Episode six point nine of
Assembly
today, where we're going to do is
we're going to write a function from
scratch.
And what we're going to do is we're
going to use parameters,
the prolog and epilog.
We're going to save registers and
then we're going to 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 how
many multiples we want to print.
So, for example, if we type three,
then we'd print off four
for the number of, say, five would
print out five, 10 and 15,
or if we did four or five, 10, 15
and 20.
And so we're going to 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 going to
define what my format string is for
printing off the data, so
I'll just define that first since
I'm at the top of the file.
And we'll just put up we're going to
use print F
so because we're going to use print
F, we need to define that as
an external function.
OK, and then in our main,
we're just going to read a number
and we were going to push it on to
the stack because we're going to use
parameters and then we
got to crack the stack.
So we'll call read.
And we will
the value of that is stored in X,
so push X.
And then I'm going to call my
function print.
And then I got to correct the stack
so I could either add DSP or I
could say
pop X, either one
works.
So now we're going to write our
function. So I'll start off
and give our function a name, which
we've already said is print
no.
Now, I'll start off with the Prolog,
so push BP,
move BP
E.S.P, come down
here and define my epilog
and I'll put a label here.
Some of these later saying, when
am I done?
So put in my epilog, put
it in my return at the end, and I've
got my own label.
All right, so we have our
parameter on the stack.
And what we're going to do is I'm
going to use SBX in order to
store what I'm incrementing stuff
by.
So.
Oh, SBX is going to count
our our number, our initial number,
sorry.
And then we're going to use Yak's
for the multiple to print and I'm
going to start that off at one.
And then I'm going to use MDX.
As the number that I need to
add and I'm going to start off at
zero because I want to incremented
inside of my initialization.
OK, so
in my initialization,
what I want to do is I want to
increment so each time through,
I want it to be one higher than what
it was before.
And then I want to use X for
my loop, so X is going to say,
how many times am I going to go in
and print off this number?
So it might be, you know, four
or five, 10, what have you.
So I'll use X for that.
And then I'm using an eBay
stack.
So if you recall,
SBP plus eight
is our first parameter.
So that should be the parameter that
is up here that's getting pushed
on to the stack because we used our
standard prolog
and then here I'm going to
copy into X
the value of X, and
so that's going to write
X is going to increment each time
and it's going to say what I'm going
to add to it. And so then each time
through it'll be the next number
in my loop.
And then we'll copy that back, so
we've incremented IDEX, copied
the incremented version and
then copied that back to Edds
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 going to print
is going to be an X, so I'm going to
push yak's.
Push my format that I want
to print, which I defined
at the top call,
print F,
and then I got to fix the stack
because I pushed two parameters on
I need to fix those.
And so I'll go ahead and
add to E.S.P.
Eight, right, because four for
each one of those
soon I'll call printf
and then when I'm all done
right each time through my
loop, I want to
add to
Yak's the value that's in Ed.
So if I'm counting my fives,
Ed will have five and X
will have five the first time and
then 10. And then 15.
And then 20 and twenty five.
And then each time
through here I want to loop back up
to 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
called top.
And so that's where I'm going to go
and print.
So this will print off, so if we
have the number one, it's going to
print off one, two, three, four,
five, if five is our maximum.
And then what we want to do is we
want to go now and do two,
four, six, eight, ten,
for our example.
So we're going to have another loop,
right. So we can't use to loop
constructs. We would have to
actually increment it
ourselves.
And so to do that, we're using SBX.
So Ebix is our number that we want
to do.
So we'll go ahead and increment
SBX
and then compare
SBX to the number, say,
10. So I'm using
10.
We can we're going to 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 then multiples of three.
So go ahead and call print
new line.
And then so I've done
my comparison to SBX
and 10, and so I can say
jump, not if it's
not zero, then I
want to go back up to the Init part.
And that's why I set up in it the
way I did.
Right. So it does some,
you know, incrementing Edek.
So the first time through Ed Exos
one. Right, because I incremented
from zero.
So now it should go to two
and then they copy two to X and then
it should still be in IDEX and
then we go through and print off.
Right. Adding the number two
each time to X which again is set
to, to.
OK, so.
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
errors, 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 out function,
it actually destroys
values for X,
Edcon, X.
So print F is messing up
our variables that we're using A for
the looping and B 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 X,
Ebix, so
our X,
X and X, so I can
go ahead and save all of those.
Before I call printf, so here I
am
calling printf
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 I'll do it.
So we're going to do pop,
pop,
pop, CBX,
pop 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 in printf messes
with my function.
Right. It won't actually hurt
my registers.
So I typed five for my number
and so write the first
loop, it's using one as my
what I'm going to increment by.
So I go one, two, three, four or
five.
And now in our function, right.
Ed becomes too.
And so that's what I'm incrementing
by. So I got two, four, six,
eight, ten and then
three, six, nine, 12, 15
doing each multiple up to
but not including the number ten.
And then if I enter the number ten.
Right. So I print off ten 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 Ebix
and ITCs,
so I'll pick a random order.
All right, so I did X,
then X, then edicts, then SBX,
so at the end of my function,
if I can get down here.
Now, my order is going to kill me
here, so let's look.
B and then D.
B and then D and
then A and then
C.
OK, 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 are getting ready.
We're calling our function
so we can.
Dump our registers.
Before and after.
And so I'll just do two
so we can see, but you
could pick a different number
so you can see is
to that gets restored.
Ebix is zero before zero
after X.
Looks like five nine eight
eight four zero.
Same thing there and then
here, Fefe.
Nine, eight, five,
four, and that is also
restored, so we can see that
we didn't modify anything
because we went through and made
sure that all of the registered
that we're using in our function, we
saved before we modified
them. And then when we got to the
end, we restored the values
back to where they were.
We used our function Prolog.
And and here's our epilog.
We used our prolog at
the very beginning, right,
and then we had to
fix the error when the fact
that another function had
obliterated our registers, we needed
to save them and restore
them before and after it obliterated
them because we wanted to
get back to the previous state that
we were at.
We also used one parameter,
right? So EBP plus eight was our
parameter. And we used 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, 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 then if you have questions, you
can contact me at Miller, MJ, at you
and Kadiatu, you can find me on
Twitter at Inelasticity.