Skip to playerSkip to main content
  • 5 days ago
Quick but thorough introduction to floating-point registers in x86-64 assembly using YASM.

Learn why XMM0 is special, how to use MOVSD / MULSD / CVTSI2SD, why you must save floats around function calls, and how easy (or sneaky) stack alignment bugs can crash your program.

Live coding + real examples converting integers to doubles and multiplying them.

Great next step after basic integer assembly tutorials.

00:00 Introduction to Floating Point Registers
00:28 Why Floating Point Uses Special Registers
01:35 Floating Point Return Value in XMM0
02:17 XMM Registers Overview XMM0 to XMM15
02:48 ABI Rules No Callee-Saved XMM Registers
03:16 128-bit XMM Registers Purpose and Size
04:00 Ed Jorgensen x86-64 Textbook Reference
05:03 Locating XMM Documentation in Textbook
05:20 Earthquake - I am going to die
06:24 Chapter 18 Floating Point Instructions
07:34 MOVSS vs MOVSD Single vs Double Precision
09:11 Understanding SS and SD Instruction Suffixes
10:58 MOVSD Example Register to Register
11:03 Conversion Instructions CVT Family
13:02 Floating Point Arithmetic ADDSD MULSD SUBSD
25:48 Program Demo User Input Section
26:01 Converting Integer to Double CVTSI2SD
26:29 Multiplying by Constant Float MULSD
28:56 Saving Result Printing Modified Float
31:38 Multiplying User Integer by User Float
33:54 Final Result Display Program Summary
35:19 Stack Alignment Crash Demonstration
36:24 Conclusion Key Takeaways
36:52 Outro Subscribe and Thanks

x86-64 assembly, yasm tutorial, floating point registers, xmm registers, xmm0, movsd, mulsd, cvtsi2sd, assembly language tutorial, x86 assembly floating point, nasm yasm floating point, double precision assembly, convert integer to float assembly, system v abi xmm, stack alignment assembly, x86-64 linux assembly, ed jorgensen x86 book

=-=-=-=-=-=-=-=-=

Thanks for watching!

Find us on other social media here:
- https://www.NeuralLantern.com/social
- Twitter / X: https://x.com/NeuralLantern
- Rumble: https://rumble.com/c/c-3696939
- BitChute: https://www.bitchute.com/channel/pg1Pvv5dN4Gt
- Daily Motion: https://www.dailymotion.com/neurallantern
- Minds: https://www.minds.com/neurallantern/
- Odysee: https://odysee.com/@NeuralLantern:5

Please show your support!

- Buy me a coffee: https://ko-fi.com/neurallantern

- Subscribe + Sharing on Social Media
- Leave a comment or suggestion
- Subscribe to Blog: https://www.NeuralLantern.com
- Watching the main "pinned" video of this channel for offers and extras

Transcript
00:00Hi there, in this video I'm going to talk about the basics of working with floating
00:06point registers in YASM x8664 assembly or YASM AMD 64 assembly.
00:18If you don't already know how to write basic assembly programs in YASM, see my other videos.
00:24This video is only going to focus on floating point registers.
00:26So for starters, what the heck am I even talking about?
00:31You know, if you have assembly knowledge up to this point, which hopefully you do if you
00:35don't see my other videos, then you know you can have some registers like RAX and RSI and
00:40RDI and sort of move them around with instructions.
00:44Let's move R12 into RSI and you can add two registers together and so forth.
00:49You can do a lot of instructions and you can store them and whatever.
00:53You also hopefully know by now that the first integer argument for creating your own functions
00:59in assembly or calling on other functions outside of your assembly module.
01:05Respecting the ABI should have RSI and sorry, RDI and RSI as the first and second arguments.
01:12And then I think it's RDX and then I think it's RCX after that, but basically you use integer
01:17registers for integer arguments.
01:20So keep in mind, we're going to start using floating point registers.
01:23In another video, I'm going to totally talk about mixing arguments and return types.
01:28But for now, I just wanted to say this.
01:30Suppose you have a function in C, let's call it F and it was going to return a double.
01:38Let's say maybe we have like a double D equals like five point whatever.
01:43And then you want it to return the double D.
01:45So then that means the return type here would be double.
01:48What this means is that a function F, it would not return its value in RAX, the normal
01:56integer return value register.
01:58Because for floating point operations, we have to use a whole different set of registers and
02:02a whole different set of instructions to manipulate them.
02:06It just doesn't work with the general purpose registers.
02:08So we can't actually, in assembly, we can't actually return a floating point value using
02:13RAX.
02:14We have to use one of the floating point registers and the one it's going to be is XMM0.
02:21We have 16 floating point registers.
02:24That's the very first one.
02:26XMM0 ironically, I guess, is always the very first floating point argument register as well
02:32as the return register.
02:34So keep that in mind, I'm going to do another video about that soon.
02:37But for now, we're going to return in XMM0.
02:40It's important to understand that we have XMM0 through XMM15 to work with.
02:45So we have like a lot of floating point registers.
02:48None of them are callies saved for the ABI.
02:51So anytime you make a function call anywhere, you should probably assume that your registers,
02:57your float registers have been destroyed already.
02:59It's kind of inconvenient if you're trying to program for performance, but of course you
03:03can save those to the stack or to memory or whatever.
03:08I'll show you that in a coding example after I talk for a little bit.
03:13Note also that all of the floating point registers here are 128 bits.
03:19The system supports 256 bits, but we're just going to use the 128 bit floating point registers
03:25for now.
03:27You hopefully are wondering why do we need 128 bits if all of our floats are usually doubles
03:32or singles that only use 64 or 32 bits.
03:36Well, you know, this just sort of allows us to do a lot more if we wanted to.
03:42In this video, I'm only going to use 64 bit floating point numbers.
03:45So just understand that when we use these registers, we're actually only using the lower 64 bits.
03:49We're not using the entirety of these registers.
03:54Let's see.
03:55What else can I say?
03:56Let's pull open a wonderful textbook that I love to show.
03:58I did not write this textbook.
04:01This textbook is by a wonderful professor named Ed Jorgensen, PhD, and he has this book
04:08called X86-64 Assembly Language Programming with Ubuntu.
04:11He releases it for free so you can literally just go to his website and download a copy
04:16of this book.
04:18That's one of the reasons why I love featuring this book at all costs when it comes to assembly.
04:24But anyway, so get a copy of this book and you can really turn yourself into an expert
04:28just by reading it.
04:30Anyway, let's assume that you have a copy of this book or maybe you just want to follow
04:34along with the video, which is fine.
04:36Let's go to section 2.3.1.6.
04:39So if you look over here on the left tab area, I'm going to click on architecture overview.
04:46And then if I expand that chapter, I can go to subsection 2.3, which is called central
04:52processing unit.
04:53And then subsection 2.3.1 CPU registers.
04:58And then section 2.3.1.6, which is labeled XMM registers.
05:03The reason we're going this far deep, by the way, I love a book that organizes their chapters
05:06this way.
05:07The reason we're going this deep is because we just want to see the XMM registers or the
05:12floating point registers.
05:13You can see on this page right here, just as I promised you, we have 128 bit registers
05:18and they start at XMM 0.
05:21They go all the way up to XMM 15.
05:22So just keep in mind there's an earthquake right now while I'm recording this video.
05:27I'm going to die.
05:28I'm going to die.
05:29I'm going to die.
05:30I'm going to die.
05:32No, I guess I'm okay.
05:34Did the camera shake?
05:35I promise.
05:36I wasn't faking that.
05:37I can't wait until the, the, the, the posts on social media tomorrow when, when people post
05:42like a chair and it's like turned over and they say, we will rebuild.
05:46Luckily, I guess I was away from the epicenter.
05:50If you were next to the epicenter, I'm sorry.
05:52I hope you're okay.
05:53Um, okay.
05:54So we're at 2.3, 2.3.1.2, it looks like the number is abbreviated over here for some
06:03reason.
06:04Oh no.
06:05Cause I clicked the wrong thing.
06:062.3.1.6.
06:07Oh, cause I scrolled down.
06:08That's what happened.
06:09Just to show you, you know, where the registers are listed in this textbook.
06:14But like I said before, we can't use the same instructions that we used to use for integer
06:17registers or general purpose registers.
06:20We have to use a whole different set.
06:21So I'm going to collapse all these chapters here and I'm going to open up chapter 18,
06:26which is entitled floating point instructions.
06:29I'm just showing you this as a reference.
06:31I'm going to write some code for you that kind of uses the registers, but I want you to
06:35know anything that you need to do with the floating point register, whether it's like,
06:40you know, operating directly on a floating point register or, you know, using two together
06:45to multiply or whatever, um, or converting between integers and floats, which you probably
06:50want to do, uh, you know, transfer data from a general purpose integer register to a floating
06:56register or back and forth.
06:57All that is in chapter 18 right here.
07:00I'm going to show you a lot of it.
07:01I'm going to show you almost all of it, uh, in the code, not really 100%, but you know,
07:06anyway, um, so you can see at the top, it just kind of like describes, you know, that we can
07:12do control instructions and so forth.
07:14The values are 64 or 32 bits.
07:17We have double precision and single precision floating point numbers.
07:21If you've seen my other videos, you understand how floats work.
07:25We know about the registers and data movement.
07:27Okay.
07:28So the first thing I want to show you is notice how we have to use a different instruction to
07:31move data between floats.
07:33So, you know, before when you moved data with just integers, you had move R 12, you know,
07:41an R 13.
07:42And what that would do is it would move the R 13 registers contents to the R 12 registers
07:46contents.
07:47Right?
07:48So with floats, maybe do a comment here, GPR, AKA into registers, Oh, my spelling.
08:00And then when we're using floats, we just have to use different instructions.
08:05So move S S and then you can do XMM zero and then XMM one.
08:11And what that'll do is it'll move the contents of the XMM one float register into the XMM zero
08:16float register.
08:18And uh, you know, what's this extra thing right here?
08:20Is we used to just have MOV and now we have this, this suffix at the end of it SS, or also
08:26in some cases, uh, SD.
08:29So for starters in this video, I'm not going to talk about, uh, manipulating multiple pieces
08:33of data at the same time with one instruction.
08:36I'm just going to talk about one instruction.
08:38We'll just manipulate, you know, one set of operands at a time, and that's it.
08:42Uh, you can sort of turbocharge the performance of your, uh, assembly programs.
08:47If you're working with, I guess, graphics or, you know, giant arrays or something like that.
08:51If you actually use one instruction to manipulate many registers at the same time or, or many
08:57pieces of data at the same time, uh, so that would, that would be a different instruction.
09:02It would look like MOV, uh, and then another letter and then the S or the D after it.
09:08So just basically understand that now this first S means we're going to, we're going
09:13to manipulate a single piece of data, or I guess a single set of operands or a, or one
09:18instruction per one thing that we're doing.
09:21Think of it that way.
09:22So all these are going to be S's.
09:23So it's always going to be move S and then another suffix after that, uh, the difference
09:29for the last part of the suffix is whether you're going to be moving single precision or
09:34double precision.
09:35So remember single precision floating point numbers are 32 bits, double precision floating
09:40point numbers are 64 bits.
09:41So basically, uh, on line six here, if I'm going to move, uh, with the S at the end, let
09:47me, let me, let me bring that back to the instruction.
09:49So it's actually normal, uh, on line six.
09:53This basically means you expect only a 32 bit, uh, uh, float single precision.
09:58And that's what you're working with, whether you're moving data or multiplying or dividing
10:02or converting or whatever you expect to, for it to be treated as a 32 bit float.
10:08Remember the way the floats are laid out.
10:10It's not just that you get more bits and thus a higher value that you can represent.
10:14Uh, when you get more bits, then different bits are designated for different uses, uh,
10:20within, uh, the representation.
10:22So it's very important to use the right instructions because if you try to interpret a single precision
10:27as a double, then the, the usages of all the different bits are not going to line up, you
10:32know, the layouts are going to be off.
10:34And so then you'll end up with nonsense data.
10:36So most of this video, actually all of this video, we're going to be using double precision
10:40floats.
10:42So that's why at the end of every, uh, uh, instruction, you're just going to see SD.
10:46So we're going to, we're going to do a single set of operands for a single instruction.
10:51And then we're going to just use a double precision floating point number.
10:54So keep that in mind.
10:56So this is how you move one float into another.
10:58Okay.
10:59Scroll down a little bit.
11:00Here's like that move SS that we talked about.
11:03Um, here's some sample code here.
11:06If you need to convert, uh, one type of float to another, like if you need to convert a 32
11:11bit float to a 64 bit float or, or vice versa, then some of these instructions will help you
11:16CVT basically.
11:18And then the designation of a, you know, single piece of data, single precision to single piece
11:23of data, a double precision that would convert a 32 bit through a 60 to a 64 bit, uh, float.
11:30And then vice versa.
11:31The next one, you can just sort of see CVT and then SD to SS kind of tells you that's what
11:36the instruction does.
11:38We're not really going to do that in the, in the, in the code, but it's important to
11:41understand that you can, uh, and all you have to do is look in all these tables here.
11:46Uh, let's see what we're going to do in the code that I'm going to write pretty soon is
11:50we're going to convert from floats to integers.
11:53Um, actually I think in the code, we're going to convert integers to floats and not back again,
11:59but you can just by looking up this, let's see, let's see, convert a scalar double precision.
12:08So here, this instruction convert a double basically to an integer.
12:12We're not going to do it and do that in the video, but here's how you do it.
12:15You'd say CVT, and then you would just look at the types, a single piece of data, double
12:20precision to a single, uh, integer.
12:24And then what we're actually going to do in our code is we're going to convert an integer
12:28value to a double.
12:30So actually not even this instruction, you can see again, CVT convert and then single
12:35integer to a single precision, uh, to a single piece of single precision.
12:40So we're not going to use that.
12:41We're going to use basically this with a, with a D at the end of it.
12:45So if we scroll down a little bit more, um, you know, convert single integer to a single
12:51piece of data, uh, which is a double precision floating point number.
12:55So that's going to show up in the code that we write in a second.
12:58And then, uh, you know, the arithmetic instructions are really, really easy.
13:02They're not as hard as the integer, uh, arithmetic instructions.
13:06If you want to just add two floats together, you just go add SD done.
13:13Here's the multiplication.
13:17We have adding, subtracting, which is easy.
13:21There we go.
13:22Multiplication.
13:23Uh, you probably have had nightmares about multiplying integers or dividing integers in
13:27the past because you had to line up all those bits in two different 64 bit registers before
13:32doing anything or after doing anything.
13:35Notice how in floats, all you have to just, all you have to do is just say multiply single
13:40piece of data, double precision, and then just provide two operands.
13:45Just two different float registers, or maybe one float register and a memory location or,
13:50or whatever you want.
13:51It's really, really easy.
13:52There's a lot of sample code in this book.
13:54I'm just going to close this now, or you can take the square, square root.
13:59I'm just going to close this now so that we can start writing our own code.
14:02Okay.
14:03Close this.
14:04And now I've got a little, uh, you know, a little code repo set up.
14:11I don't have anything in my assembly source code file, so we're going to write that together.
14:16Let me just double check.
14:17We're at 16 minutes right now.
14:18This video is going to be long.
14:19Okay.
14:20Okay.
14:21So what I want to show you first, I guess I'm not going to show you the make file because
14:28this is not a video about make files.
14:30Again, if you want to know how to compile, assemble, link, generate make files, understand
14:34hybrid programs and drivers and things, all that is going to be covered in another video
14:38or was covered in another video.
14:40So just trust me in this video for now.
14:44We have a make file that just sort of compiles a hybrid program.
14:48We're going to have a driver, which is just a C plus plus program.
14:53And all it does is just, you know, basically say hello.
14:56And then it asks for a double return value from a function that returns a double.
15:02That function, that function called floater is going to be our assembly module, or it's
15:06going to be inside of our assembly module.
15:08Then it's just going to print the value it received and then just exit.
15:12So that's all it does.
15:14And we have an extern C module to disable name mangling so that our C plus plus module
15:20can call on an assembly function.
15:22So if we go inside of our assembly source code file, there's nothing again, if you want
15:28to know the basics of Yasm assembly, see my other videos for now.
15:32I'm just going to paste in a bunch of code and just quickly talk about it.
15:38So we have a data section here and you can see all I have up above is just a bunch of
15:43strings.
15:44I'm just going to print, you know, Hey, give me an integer.
15:48Here's the integer that you entered.
15:49Now give me a float, please.
15:51And then here's the float that you entered.
15:53Oh, whoops.
15:54Did I include my other thing here?
15:56Hang on.
15:57Let me grab some code from somewhere else real fast.
16:01Doop doop.
16:02Hmm, man, there are like so many things.
16:06Okay.
16:07I got to grab some of that.
16:09Long story short, this shared object helps me print and input floats and integers.
16:14You don't need it in order to understand what's going on.
16:18You could just inspect your program with GDB, which I already have another video on, or you
16:23can use a different library or printf or scanf, whatever you want to input and output floats.
16:31But I just like to use that one.
16:32So your, your mileage may vary anyway.
16:36So then I have a CRLF because I like to be able to just kind of call a function to get
16:40a new line.
16:41And then we have some variables to hold our floats.
16:46So since we're going to be using 64 bit floating point numbers, that means they're eight bytes,
16:51which means they're a quad word.
16:53So when I'm declaring my floating point numbers in the data section, I can just say DQ for quad
16:58word, and it will work the same as our integer memory locations.
17:03The only thing that's different is when you're initializing a value, you have to put a decimal
17:07point here.
17:09Unless you intend to totally erase the initial value, you know, the moment the program starts,
17:14you'll end up with some really, really bad data if you don't, if you don't put a decimal
17:18point here.
17:19So for example, if I made the mistake of saying, let's have a float multiplier and we'll make
17:25it a quad word and it'll be the number three.
17:28And then later I try to use that as if it were a float.
17:31It will not work at all because the system is going to see the three without a decimal
17:35point.
17:36And it's going to assume that I mean two's compliment for assigned integer.
17:39So then it's going to stick a number in that memory space that looks and works like an
17:45integer.
17:46And then later I'm going to try to multiply that as a float.
17:50And then, and the result is going to be totally bizarre.
17:52It's not going to work.
17:53So make sure that, uh, even if you're going to, even if I wanted to multiply something
17:58by three, just, just three, I would have to put 3.0 to let the system know that, uh,
18:03the three value should be laid out in terms of a float and not an integer, not two's compliment.
18:11Okay.
18:12Then I just have like system call one to print something to the screen and then standard output,
18:16which is file descriptor one.
18:18You can see my other videos if you don't know what that is.
18:20Now let's start the text section of our program.
18:24So for starters, I'm going to be using some functions from my external library that I talked
18:28about.
18:29All I'm going to do is just, uh, you know, use my library so that I can print and input
18:34integers.
18:35And then so that I can print and input floats.
18:38That's pretty much it for that.
18:39So, you know, you can, again, you can use scanf or a printf, uh, if you don't have access
18:45to this library, uh, now let's, uh, program our entry point.
18:50So I'm going to do this.
18:54And so if you recall in our driver, the driver was going to call a function called floater.
18:59We put it in the name demangling, uh, section extern C, and we said it was going to have
19:04a double return type.
19:05So if we look back here, you know, the, the function name is floater, just like what the
19:10driver was going to call on.
19:12So that's great.
19:14And notice how we're going to return some data to the caller, but we're not going to be using
19:18RAX.
19:19We're going to be using XMM zero again, XMM zero is always the return register.
19:24When your function returns a float, you might be wondering at this point, what about RAX?
19:30Is something going to be done with RAX?
19:32Well, you know, in your higher level code, as soon as you say that you want to double
19:36from a function that is a double or that it returns a double, uh, the RAX register is just
19:42going to be ignored.
19:43It doesn't really matter.
19:45So return your data in XMM zero always, uh, when you are returning floats.
19:50Okay.
19:51So then I have a function up here called a float convert tests and another function up here
19:55called CRLF.
19:57I'm just going to import some of my, uh, I guess, busy work code that you don't really
20:02need to learn about in this video.
20:04Um, so for starters, I'll just, I'll mention it real fast just so that you know what's going
20:10on.
20:11But, uh, I explain in another video how to write a function called print null terminated
20:16string, just to make sure it's easy to print these strings.
20:19Notice how I'm not specifying the length of these strings in advance.
20:21I'm just tacking a null terminator on at the end, uh, that's explained in another video
20:27and, um, print null terminated string relies on a function I wrote called string length,
20:32which you have in the C library.
20:34Also, uh, I didn't write the one in the C library.
20:36I just wrote my own right here.
20:38And all this does is it just computes the length of the string based on a null terminator
20:42so that, uh, the printing function can just, you know, take the length and just give it
20:48to the system call so that I don't have to pre-compute it.
20:51And then the CRLF function, all that does is it just prints out a new line, basically
20:55using print null terminated string.
20:58Okay.
20:59So not really that much has happened.
21:01At least we know how CRLF works at this point, um, you know, let's comment this out and see
21:07if the program actually runs make run again, make files are covered in another video.
21:12Okay.
21:13So it works.
21:14It's just sort of like doing nothing, but it works.
21:17Let's go back up to my code here and we'll start the main function, uh, float convert tests.
21:25So let me uncomment that.
21:26And then I'm going to start it up.
21:30Doop, doop, doop.
21:34Okay.
21:35So float convert tests.
21:36So this is the start of the function.
21:37It takes, uh, no arguments.
21:39It doesn't return anything and it just uses register 12 for the integer that the user is
21:44going to input.
21:45Pass the user for input and we're going to save that there.
21:49That means, uh, well, first, because this is a function, I have to have a return statement.
21:54And, uh, if we're going to respect the ABI, R12 was marked as a callee saved.
21:59So we have to say, this is the prologue and we're going to do a preservation of R12 with
22:03a push pop pair.
22:05Hop.
22:06R12.
22:07R12.
22:08Okay.
22:09So that's done.
22:10Next thing that we need to do is, uh, well, okay, spoiler alert.
22:14This program is going to crash because of stack alignment.
22:16I have another video out already that talks about stack alignment and why your program might
22:21seem to mysteriously crash for no reason at all.
22:24The solution for this particular program is just, we'll push another nonsense value onto
22:29the stack so that the stack will be aligned.
22:33And therefore, uh, any calls to GCC related libraries won't just crash the entire program.
22:38So just trust me on this.
22:39If you don't understand, go see my other videos.
22:42So the first thing we're going to do inside of this after we've preserved R12 is just ask
22:46the user for an integer.
22:48So I'm going to use my print null terminated string function.
22:52I'm going to give it two arguments.
22:53I'm going to say, Hey, here's a message that I want you to print to the user.
22:57Please print, you know, please input, please input a string.
22:59And we want to print it to standard output.
23:01If you don't understand function calls, see my other videos.
23:05And then I'm going to call on my library just to input.
23:08A, uh, sign to 64 bit integer from the user.
23:12And then I'm going to steal or save that, uh, inputted integer into R12.
23:17That's all I'm going to do for now.
23:19Let's run the program again real fast, just to make sure that it works.
23:22I'm going to go clear and make run.
23:27Enter an integer.
23:28And then I entered it and then nothing happened.
23:31Okay.
23:32So then the next thing I'm going to do is I'm going to grab a float from the user.
23:36So I'm just inputting two numbers right away.
23:39So, uh, same thing as before.
23:42I'm just asking the user with a printed message to make the program nice and pretty, you know,
23:45Hey, could you please input something?
23:47Then I'm calling on a function to input a float from the user.
23:52And then I'm using my first floating point instruction here.
23:55Move SD.
23:56So, I mean, think about what we said before move means let's move something.
24:00If there's an SD at the end of it, that means we're going to do, you know, one thing for
24:04one instruction.
24:05We're not going to have an instruction that moves many, many pieces of data at the same
24:09time.
24:12And so that's where the S comes from.
24:13And then the D means double precision.
24:15So that means I'm expecting that XMM zero is a 64 bit integer or sorry, 64 bit float.
24:22And I want to move it into a memory location that I've created up above called the float.
24:29So you know, to be fair earlier, I said all of your floats, they should have a decimal point
24:34since I didn't actually use the float before setting it.
24:38I could have put any number I wanted here and it would have been fine because it would
24:41have just been overwritten at this point.
24:45So I'm now grabbing a float from the user and I'm saving it.
24:50And you know, I guess I could have saved the, I guess I could have saved the float somewhere
24:56else.
24:57But remember, every time you make a function call anywhere, you should expect that the floating
25:00point registers have been destroyed because the API does not, the application binary interface,
25:06you know, the standard that we're using.
25:08It doesn't say that any of the float registers are callee saved.
25:11So any, any function that you call, including system calls is allowed to destroy the floating
25:16point registers.
25:17So I'm just saving it right away anyway.
25:21So let's just echo the integer back to the user.
25:23This is still pretty basic stuff.
25:25I'm just saying, uh, let's print a message saying, here's the integer that you entered.
25:32And then, um, I'm going to move our 12, which was the integer that they entered into
25:38the first argument.
25:39And then I'm just going to call my little function here with a CRLF.
25:41So this should work.
25:44Let me just double check that this still runs.
25:49Enter an integer 75, let's say in a float 3.4.
25:52And then the integer you entered was 75.
25:54And so that's all we have right now.
25:57So we're getting a little closer to working with our floats, echo the integer.
26:02So now let's convert the integer to a floating point number.
26:05So we can start working with it against the floating point number.
26:10I'm going to just paste my code here and explain a little bit.
26:13So we're going to convert the integer to a float and then multiply the float by a float
26:18multiplier number.
26:19If you look up at the top of our source code, I just put this number in here just because
26:23I felt like it, you know, float multiplier 3.333.
26:27And so, uh, what's going to happen now is we're taking our 12, which was the user's, uh, uh,
26:32integer input.
26:34We're going to move into XMM zero.
26:37And then we're going to use the convert instruction that we looked at earlier.
26:40So CBT means let's convert something like between float or whatever.
26:46And the first, uh, operand should be, sorry, the source should be a single integer.
26:52And then the, uh, the destination will be a single double precision floating point.
26:57And then the two in there just means convert one thing to another thing.
27:00So convert a single integer to a single double, single double sounds weird, right?
27:07But at that point we should now have the user's input inside of XMM zero instead of R12.
27:13And the reason for that is, uh, you know, we want to be able to multiply two floats against
27:17each other.
27:18We can't directly multiply an integer against a float.
27:20We have to do some conversion first.
27:22So that's why we have this here anyway.
27:24Now that we have the user's input as a float, we can multiply it by other floats.
27:30So again, just mul for multiply, and we're going to do a single piece of data and it's going
27:35to be a double precision floating point number.
27:38And basically I want to take that float multiplier that I set up up above and multiply it against
27:45the float converted users integer input, and then get a result.
27:51I'm going to grab the result.
27:52The result is going to be an XMM zero.
27:54If you haven't seen my other videos about the basics of, basics of assembly, uh, go see
27:58them now.
27:59But basically you should know at this point that, uh, if you only have two operands with
28:02this sort of function, then the first operand is not only going to be part of the source,
28:07but it's also going to be the destination.
28:08So XMM zero at this point in time now contains the result of multiplying the user's integer
28:16against the float multiplier.
28:17And we're allowed to do that because we converted their integer to a float first.
28:21We're going to store the result in a variable up above called the modified float.
28:26So if you look up, we just have like another quad word, call it the modified float.
28:31And again, because I stored it before actually trying to use it, I could have put any number
28:36here if I wanted to, but you know, it's just safer to stick a valid floats in there at first.
28:41You never know how you might change your program and forget what you're doing.
28:45I do that all the time.
28:47So we've converted that and stored it.
28:50We've converted and multiplied and stored it.
28:52So let's tell the user what we've done.
28:56So we're going to basically print a message to the user that says, Hey, here's the modified
29:00float.
29:01And then we're actually going to print it using my print float 64 function that I have.
29:07And again, you can use printf or whatever you want to actually print things.
29:13So we're going to use the move instruction for floats.
29:15And we're going to say, let's move a single piece of data.
29:19And we're going to move a double precision floating point number.
29:21And we want to move from the modified float to XMM zero.
29:26And you may be wondering what's going on.
29:28Why are we moving the modified float back into XMM zero?
29:31Didn't we just have XMM zero?
29:34Remember anytime you call any function, all your float registers could be destroyed.
29:38So just simply printing a message to the screen, we already can't be sure that XMM zero is preserved.
29:45So that's why I saved it right away and then I'm going to pull it back out right before
29:49I make this other call to print it.
29:54So remember XMM zero is not just the return register for double returns or single precision
30:01returns.
30:02It's also the first float argument for function calls.
30:06So if I'm calling this function here, that's the reason that I loaded up the float into XMM
30:10zero.
30:11I'm basically telling this function, you've got one argument.
30:14It's a double.
30:15There you go.
30:16Please print it for me.
30:17Let's see if this actually works.
30:18I'm not sure if I need to add some more stuff.
30:20Okay.
30:21I think it should probably work.
30:24Okay.
30:25Enter an integer.
30:26I'm going to say 11, enter a float, let's say 2.1.
30:31And then it says the integer you entered was 11 and the modified float is 36.663, whatever.
30:39Let me double check.
30:40That makes sense with a calculator that's taken forever to load.
30:44So if we did 2.1 times 3.3s, we end up with a 6.
30:53What did I do wrong?
30:54I think I misinterpreted my own code.
30:56We told the user about the modified float.
30:59The float was the multiplier.
31:01So we multiply their integer by the modified float.
31:06Oh, I think I multiplied the wrong number.
31:09Let me, let me just fix that.
31:12So 11 times 3.3.
31:15Okay.
31:16So that's, yeah.
31:17The modified float is 36.66, whatever.
31:19And you can see that's the actual value.
31:21And so the, the, the program took the integer, it turned it into a float.
31:26You can imagine 11.0 now, and then it multiplied it by 3.3333.
31:30And then that's the number that we're seeing here.
31:32Okay.
31:33So we're almost, we're almost finished.
31:35Tell the user about the modified float.
31:37The next thing that we'll do is we will multiply the integer by the float.
31:41So the user entered an integer and also entered a float.
31:44And we're just going to multiply them together, which you are allowed to do if you converted
31:49first.
31:50So, excuse me.
31:55So we take our 12, which was the user's original integer input, and we convert it back into XMM
32:03zero.
32:04Remember we lost XMM zero.
32:05I guess we could have stored that somewhere if we wanted to, but I'm just going to convert
32:08it again with that same instructions before.
32:11And then I'm going to multiply it single piece of data, double precision by the float that the
32:17user entered.
32:18So, you know, if you scroll back up, we are storing their input right here into the float
32:25global variable, or I guess, module global variable.
32:29And so we're just saying the user's input multiplied, whoops, the user's input multiplied by the float
32:39and then store that inside of XMM zero.
32:42And then, sorry, my bad.
32:46We're converting the user's input to XMM zero.
32:49And then we're multiplying it on that next instruction.
32:53And then finally, we're going to save the results somewhere.
32:55So XMM zero at line 117 now contains the result of multiplying the user's integer by the user's
33:03float, both things that they entered.
33:05We're just going to save it into this memory location or this global.
33:10After we're done saving it, then we can pretty much just tell the user about it.
33:14And then we'll basically be done.
33:17Maybe I'll show you how to crash the program with stack alignment just to prove to you that you should go watch that video.
33:22Anyway, so we're going to print to the user, hey, here's the result of multiplying your integer by your float.
33:28So just these three lines right here.
33:31And then we're going to take the float result that we saved.
33:35We had to save it because XMM zero can be erased just by one function call.
33:40So we grab it again from memory.
33:42We stick it into XMM zero and then we just print out the float.
33:46So basically we're multiplying the user's integer by the float and then we're telling them here's the result.
33:51And then we're just going to print the result.
33:53And that's it.
33:54Let me see.
33:55Is there anything else that I really need to show you?
33:57I think that might be it.
33:58Let's just make sure that the program works.
34:00So I'm going to do clear and make run.
34:03Please enter an integer.
34:04Let's say 12 and enter a float 2.3.
34:09And then it's saying the modified float is 3.9.
34:13So I think that's what we kind of looked at before the user's 12 input ends up being a 39 and float.
34:20But then if we multiply the 12 by the 2.3, then we get 27.6.
34:30The integer multiplied by the float is 27.6.
34:34So now we know how to do all sorts of manipulations between floats and integers and just floats against themselves.
34:41Notice how the driver, it received a value back from the caller.
34:46So like, you know, basically at the top right here in my, in my like main area of this floater function,
34:53I'm just saying the modified float, let's return that to the caller in XMM 0.
34:59And then when the driver said, I want a double value equal to the call of floater, that's, that's how it got that.
35:07And then it just kind of printed it here.
35:09I guess it, maybe it would be more fun if we just stuck the int multiplied by the float in the return value.
35:14But I guess you probably understand by now you can return any float that you want there.
35:19The other thing that I just wanted to do real fast before we stop is show you that we will probably crash the program if our stack is not in alignment.
35:28So integer and then a float, everything seems to work.
35:32But notice how if I take away this extra push pop pair.
35:39Now the stack is going to be about eight bytes shifted from where it was before.
35:44And that might not be good for the GCC libraries, which I think my float printing or inputting instructions might use.
35:50I got lazy and I just, I think I decided to use printf or scanf or something under the hood for the float stuff.
35:57Whereas I was doing it by hand for my integer stuff.
36:00So let's see, it should crash 44 and then 4.4.
36:05Yeah, there we go. Seg fault.
36:07So again, mysterious crashes.
36:09If you are absolutely sure that your programs work, you might be a victim of stack alignment.
36:14And you probably want to go watch that video just to make sure you understand how to mitigate stack alignment issues when linking against GCC.
36:24We're using GCC calls or anything.
36:26Okay. So I think that's everything that I needed to show you.
36:29You are now a, an expert at the basics of floats.
36:35You can probably become an expert with just a couple of watches of this video.
36:38And if you read throughs of that textbook and maybe some practice programs.
36:43So thank you for watching this video.
36:45I hope you had a little bit of fun and learned a little bit of stuff.
36:48I'll see you in the next video.
36:53Hey everybody.
36:54Thanks for watching this video again from the bottom of my heart.
36:56I really appreciate it.
36:57I do hope you did learn something and have some fun.
37:00If you could do me a please, a small little favor.
37:03Could you please subscribe and follow this channel or these videos or whatever it is you do on the current social media website that you're looking at right now.
37:11It would really mean the world to me and it'll help make more videos and grow this community.
37:16So we'll be able to do more videos, longer videos, better videos, or just I'll be able to keep making videos in general.
37:22So please do, do me a kindness and, and subscribe.
37:26You know, sometimes I'm sleeping in the middle of the night and I just wake up because I know somebody subscribed or followed.
37:32It just wakes me up and I get filled with joy.
37:34That's exactly what happens every single time.
37:36So you could do it as a nice favor to me or you could, you could troll me if you want to just wake me up in the middle of the night.
37:41Just subscribe and then I'll, I'll just wake up.
37:43I promise that's what will happen.
37:45Also, if you look at the middle of the screen right now, you should see a QR code, which you can scan in order to go to the website,
37:52which I think is also named somewhere at the bottom of this video.
37:55And it'll take you to my main website where you can just kind of like, see all the videos I published and the services and tutorials and things that I offer and all that good stuff.
38:04And, uh, if you have a suggestion for, uh, uh, clarifications or errata or just future videos that you want to see, please leave a comment.
38:15Or if you just want to say, Hey, what's up, what's going on?
38:17You know, just send me a comment, whatever.
38:19I also wake up for those in the middle of the night.
38:22I get, I wake up in a cold sweat and I'm like, it would really, it would really mean the world to me.
38:27I would really appreciate it.
38:28So again, thank you so much for watching this video and, um, enjoy the cool music as, as I fade into the darkness, which is coming for us all.
38:49So again, thank you.
38:57Enough of this video you will hear.
39:0115
Comments

Recommended