13 hours 15 minutes
Hello. This is Dr Miller, and this is Episode 15.1 of Assembly.
Today we're gonna talk about 64 bed assembly. We'll talk about the registers, deprecate ID instructions and then calling functions.
So 64 bed assembly.
So what is 64 bit assembly, while 64 bit references a number of bits that are used for memory, a justice.
So when we use 64 bits, that allows us to address to to the 64 minus one bytes of RAM,
and this is equivalent to 16 exabytes.
Now that is to be contrasted with 32 big. So 32 bit allows us to address to the 30 to minus one bytes of RAM or four gigabytes.
And so a lot of computers nowadays have the ability to have more than four gigabytes of RAM. And so you have to use a 64 bit OS in order to,
um, used that. There is an extension called P E that will allow you to address more than four gigabytes, but it's just easier to use a 64 bit
I'm processor and then our registers air adjusted for 64 bit assembly, so they are larger sized, and we have more registers
and then things like pushing pop. Those stack operations are then adjusted based on those new sizes.
So one of the other things that was created was processor cores. That's sort of the same time that we had 64 bit. We also had multiple CPUs per processor,
and so the cores would have a shared memory. And then they allow your computer to do, um, what we call multi programming or multi processing. And that's for the ability for that computer to do more more than one thing at a time
before we had multi core processors. If you just had a single core than the processors would switch in between different things as fast as it could in order for it to appear like you were watching a video and listening to music and editing a document at the same time.
And then the core two duo was one of the first ones, and so this was in 2006. So this is a desktop
ah, processor that was used by Apple, and that sort of brought in multiple cores and then 64 bit chips.
Now the chips, even though they're 64 bit have the ability to run 32 big code. So they maintain backwards compatibility if needed.
And then our core counts have gone up. So core two duo had two processors. Um, then they had quad core and a core 16 core an hour up to 32 or 64 course.
Um, that can be on some of the new rising chips.
Now, the operating system will basically select which course in or to run a process on. And then we have a process where the processor or the OS will migrate over the stack and the registers, so those have to be saved and then restored. If you're moving
it to another core that might not be on the same die,
So instead of the e prefix we have the r prefix. So instead of yea X, we have our x r b x r c x rdx.
We have our s I r g i r b p r s p And then instead of the flags, we have our flags. And then instead of the i p, we have r i P.
Additionally, they added another set of registers so are eight through our 15. So instead of
trying to make up more letters, they just picked numbers because that was easier.
And then we also added a new addressing mood. So R I p allows memory relative addressing so you can have, um, memory
addresses that are based on the current instruction pointer. And so this will make code that can be more portable, much easier in 64 bit versus 32 bit.
So here is a diagram that I pulled from Wikipedia that has all of the different sets of registers on a 64 bit OS, and we can see that
we have some of the ones were used to, so e x e b x s e x e x and their smaller breakdowns. But we also have our are a x r B x r c x rdx.
We see our floating point processors here. We're going to see some status bids over here. Um, some special tables. So CS ds, yes,
Um, ss those air in there. Um and then you've got your additional are registers. So are eight through our 15 that are included in there,
and then we have some xmm. Why M m m and Z mm registers that are in there. And we'll talk about those some of those a little bit later
so we can see that we have more registers available to us that we can use in order to do programming.
So one of the things we need to talk about his deprecate ID instructions. So, for example, a couple of instructions that are deprecate id our push a d and pop 80.
So if we look inside of our library functions and our normal main functions, we use push a d and pop 80 to push all the registers and and pop them back off.
And so all of the library functions are not going to work. So in the semi Oh, include,
none of those functions will work because they all rely on this push a d pop 80
um, set of instructions
now calling functions.
So when we have 64 bit, we have the ability to use fast call. So most modern OS is are going to use what's called fast call. So instead of pushing things onto the stack where the stack is much slower than normal, Ram, we're just going to use registers for him. So if you only have a few
arguments than those arguments can be put in registers and it will actually execute much faster because RAM is is orders of magnitude slower than the processor. And so if we can avoid having to hit Ram than it's gonna go a lot faster.
So, for example, Lennox uses the 1st 6 imager or pointer. Arguments are passed in R D I r s I r D X R C X and then are 18 or nine.
And then, if you have MAWR beyond that, than they have to go on top of the stack.
Additionally, Ah, lot of new versions of GCC rely on libraries like print F, right, so print F is in a shared library. It's in standard I standard ioo dot h, and so if you're going to use some of the new versions of GCC, you have to use what we call pick code or position independent code,
um, and that is used to create a pie or position independent, execute herbal,
and what these air doing is they allow the different parts of the program to actually lie in different parts of RAM, and that helps with things like address bracelet ran musician SLR,
um, to be able to relocate that execute herbal in a quick fashion. And so they're going to be a couple things that we might have to do depending on what you're doing. You might have to do that in order to create your code.
So here there's a couple of things to point out here. So if we see at the top, we can see that we are able to create a quad word. So I got feed beef, be feed,
um, in a quad word.
And then when we're loading it, we can use our S I and so we can load the whole
64 bits of that in two R s. I. So the memory load will actually load all of that in there. And then here I wanted to print off 64 bits and hex. So the L X is for a long
hexi decimal 0 16 So zero means we have leading zeros, and then 16 means that you're gonna have 16
um, hex digits that get printed off,
and then we have to move things appropriately. So our format string or testing is going to go into RD I The value is going to go in tow. Rs I. So that's the first argument for that format string for print F
with Brent if you have to set our E X 20 and then we can call print F. But one of the things with the position independent code is that we have to talk about the PLT. So the plt is the procedure linking table.
And so what this does is it provides a mechanism to resolve dynamic libraries.
And so some of the versions of GCC will require you to say WRT or with respect to the PLT or with reference to the PLT. So that way it knows where to look up the printout function. Call it something that we haven't had to worry about previously. But
if you're going to do some of the newer versions using 64 Bay, then you have to use those type of references.
If you're quoting something in, see that, it'll automatically put in those references appropriately,
and then we can see here. I've removed the push a D in the pop A D. And then, as with our normal function, we can move yea x zero and exit.
I also did change this, so it's just a main function. So if you do that, if you could create just a main function, then you are able to just compile the entire thing with GCC after you create your l file.
So here's the example. Make file for creating that. And so the doom Nazem and then minus F will specify the file type. And so instead of just saying Elf, we say Elf 64. So this is to make a 64 bit object file
and then we can use GCC in order to compile that because we had a main in there, we don't have to have the driver
dot c weaken. Just directly compile that and it will create our binary 15.1 for
So today we talked about 64 bit assembly. We talked about the additional registers, some of the deprecate ID functions that we can't use in our library anymore, and then a couple of things that we had to know in order to call some library functions. If we want to use some newer versions of GCC
So looking forward, we're going to talk about Emma Mix. We'll talk about SSE and then A s, and I
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 no house 30.