Hello, this is Dr. Miller, and this
is Episode six point eight of
Assembly
today we're going to talk about
saving the Register St..
So saving registers, so
when you are in a function, you
might have a set of registers that
are doing something and
before you call another function,
you will want to maybe save those,
right, so that you don't ruin them
while you're in the function.
And so there are a couple of
different approaches to this.
So the first is to basically
push all of the registers that are
modified.
So you keep track of which register
did I modify?
If I didn't modify it, then I don't
need to save it.
You also could push all of the
registers, so just push all the
general purpose ones and then
you don't have to worry about it in
the end.
And then we can also push the flags.
So saving registers one at a time.
So what you want to do is you want
to figure out which registers
that you want to save onto the stack
and then you pick a certain order.
So here I did X and then X
and then Ebix.
That order could be any one that you
choose.
You do your normal function stuff.
So you modify the registers
and then when you pop them off, one
of the things to remember is that
you need to go in the opposite order
that you push them.
Right, because they stack is a last
in, first out.
And so if the last thing that I
pushed is SBX, then the first thing
that I need to restore is X
and then X and then
X.
And so when you enter your function,
you do your prolog as normal and
then you would save any registers
that you need and then you do
the function stuff and then at the
end you'd restore them and then you
can exit using the epilog.
Now, the second approach is to
basically just save all of the
registers and so you can use a
command like push aid,
so that stands for PUSH and
then as for all and then demeans
these words. So we're using the
extended registers.
And so this will save all of them
and it saves them in a weird order,
so X then X
than Ed, X than SBX
than the ESP when it started
SBP, USSI and Eddi.
And then the opposite command for
this is Pop HÃÂ©di.
So it goes in the reverse order.
So Iida as first SIEV
X X
and then find the X and
then Hesp is restored back to the
state that it was before this
call was issued.
And then if you're worrying about
flags, so if you maybe set a flag
using a command like a COMPAR
or something like that, you can
basically save all of them and
it uses the double word and
you can use push F.D.
to save all of the flags onto the
stack and then pop dfd to restore
them from the stack.
And this is if you had flags and you
were worried about them being
modified in the function,
or if you're in your function, you
are going to modify them and you
don't want to mess up somebody else.
Now keep in mind, all of this saving
is taking extra space and taking
extra time.
So it does take extra cycles for it
to save the data to the stack.
And the stack is stored in Ram
and RAM is slower than the CPU.
And so there comes a performance
penalty when you save all of these
registers.
So let's do some examples.
So first, we're going to save some
of the registers and then we're
going to save all of them.
And our first one, we're actually
going to go back to an example we've
previously done.
So this is a function that we looked
at previously,
and we can see this is the mod
function, and so
if I'm going through this function,
I need to look at my body and see
what registers do I modify.
So it looks like I modify X
and X and
X and then I do a divide.
And that is also going to modify X
and X and then I save
my result.
And so here the results of my
function is going to be stored in X,
so I don't want to save that and
then restore it, because then all of
the work that I did in my function
will be useless.
But I do want to save maybe X
and X, so
I come in here, pick an order that I
want to and say push X,
push X,
and then at the end I want
to restore those.
So pop and then the reverse order.
MDX
pop e, c, x.
And now my function should still
work as normal, but now it hasn't
modified those registers.
It saved them and then restored
them.
And so it should still work.
All right, and then the second
example.
We're going to use the push
aid now,
it's kind of interesting because
inside of our function, we did use
push a and pop, which
are pneumonic, same pneumonic.
So they'll push all those registers.
But let's just look at what it does.
So if we give ourselves some values
here.
So move one into X,
move
to an X,
four into DCX.
Eight,
16,
just picking registers that are
going to get saved.
OK, and then
what I want to do is I want to save
all of my registers so I can
say push ahead
and I'm going to give this a label.
So that way, when I'm debugging, I
can just just set a break point
for that label.
And then I can do some extra work so
I can say something like move
yak's 20,
SBX
30, DCX
40, the
ESSI
60.
80.
And then I'll go and I'll restore my
registers, so pop poppyseed.
All right, and then we're just going
to run that a bugger so that we can
kind of see what's going to happen,
so gdb
six point eight
and then because I put that label
in, I can just say break and then
here. So it's a nice, convenient
way to do that.
So then I can start running type
are.
And so we've issued all of the
commands to modify Ebix
so we can see that the values of our
registers have been set,
right? So we set Yaqub, X,
X, SBP,
IACI and Eddi all to different
separate values, and then we're
going to issue the push function.
So we should see all of those values
go here into this stack.
So all step
my instruction, so now we can
say, see, yak's,
I think SBX X,
ed X, you've got our
stack pointer SBP.
Um, the CSI
is 10 and is 20,
so we can see that those are saved
onto the stack and now
we'll just go through and we're
modifying all of these registers.
All right. So we got to the point
where we modified each one of them.
Right? So now they're completely
different values. And we had before
and I left sort of E.S.P alone.
And then when I do the pop a.
We can see that our registers got
reset back to what they were,
so we were able to save them and it
saved them in a particular order,
and then we were able to restore
them using the pop function.
And then I can finish the program,
which doesn't do anything.
So today, we talked about saving
registers in a function and either
doing that by saving all of the
registers or doing it by
saving the ones that we modified,
and generally the approach
would be to save the ones you modify
if you know which ones are going to
be modified.
And then if you have flags, we
learned how to save those flags in a
function.
So looking forward, we're going to
have a more complicated example
that uses the stack and parameters
and then saves registers that we
were modifying.
So here's our quiz.
So what is the command
that will save all of the
general-purpose registers?
Parishad.
What is the command that will
restore the flags again, assuming
that you have saved them?
Pop, F.T..
So if you have questions, you can
contact me at millirems, at you and
Kada Edu and you can find me on
Twitter at Milhouse 30.