Mixed Function Arguments in x86-64 Assembly – Integers & Floats Explained

Mixed Function Arguments in x86-64 Assembly – Integers & Floats Explained

Quick guide to passing mixed int + float arguments in x86-64 assembly (System V ABI). See why rdi can still be the first integer after several doubles, why xmm registers count separately, and how return values switch between rax and xmm0. Perfect for YASM/NASM programmers interfacing with C/C++.

Intro to Mixed Arguments 00:00
Simple Integer-Only Functions 00:46
Adding Arguments and Return Values 01:01
Integer Arguments in RDI and RSI 01:30
Pointers Treated as Integers 02:06
Introducing Floating-Point Returns 02:31
Returning Double in XMM0 03:06
First Float Argument in XMM0 03:36
Float Registers Count Separately 04:03
Integer Register Order Explained 04:16
Separate Counting for Integers and Floats 05:21
RSI as First Integer After Float 05:38
Reference to Ed Jorgensen’s Book 07:00
Callee-Saved Registers Overview 07:56
Complex Mixed Argument Examples 09:48
Inserting Integer Among Floats 10:57
Skipping Float Registers on Integer 11:18
Calling C from Assembly Notes 11:56
Name Mangling Reminder 12:21
Closing Remarks and Thanks 12:30
Call to Subscribe and Support 13:04
Website and QR Code Mention 13:38
Final Thanks and Outro Music 14:19

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

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 the Blog: https://www.NeuralLantern.com
  • Watch the main “pinned” video of this channel for offers and extras

Hey everybody! In this video I’m going to talk to you a little bit about using functions with

mixed arguments in a YASM x86-64 assembly language program. Although this

video will probably still be useful to you if you’re using NASM or MASM because the

mixed arguments and their order and how they work is governed by the ABI which is a system

so what the heck am i talking about okay so the first thing that i want to show you is uh

imagine we have a function here let’s say void f this function doesn’t take any arguments and it

doesn’t return anything congratulations you’re done that was the easiest thing that you’ve ever

done in your entire life but as soon as you start adding arguments to it you have to uh

start understanding how to uh how to call registers and stuff so imagine we have like a

a long a and a long b so we give it two arguments and maybe we want it to return a long

this is kind of like level one of writing functions in assembly right we just have

a bunch of integers and we realize okay um this long the return value is going to come to the

Maybe I’ll do a comment up here, we’ll do rax, we’ll say the long is actually coming

back to the user in rax and the long is coming into the function with rdi, the long a and

the long b is coming into the function with rsi.

So if you understand this then you can write a function in assembly where basically you

two incoming integer arguments and then you return to the caller a long value using rax

keep in mind also that if this second argument was a pointer long pointer then it would be the

same thing rsi because pointers are integers they’re 64-bit unsigned integers even if the

pointer was not to a long even if the pointer was to a double or a character or whatever it would

pointers are integers. It starts getting a little bit more complicated when you want to mix between

floats and numeric arguments. So what I’ve been saying so far, it’s all just integers.

Even if we’re mixing pointers with regular longs, it’s just, you know, they’re all longs basically,

right? So, but as soon as we start introducing floats, then things get a little bit more

complicated. So for starters, what if we did a function that was, that returned a double?

that returned a double. So let’s say we have a function G and it returns a double. Maybe it

still takes in a long and a double pointer. If it returns a double, let’s see, is this still

lining up? I don’t think it’s lining up anymore. There we go. If it’s returning a double, then

that means we have to return to the caller with the XMM0 register. So XMM0 is always designated as

the well the first float argument but also the float return value so keep in

mind if I’m returning a double to the caller I’m not going to use our a X at

all I’m just going to use XMM zero load it up with the return value and then

return to the caller and that’s it if I wanted to do another function let’s say

hmm how about H and then we’ll say I don’t know maybe the first argument is a

argument is a float we call it a double a that means rdi is not going to be the argument that

or the register that we look at to see our incoming double it has to be a float register

xmm0 is the float register that we look at for the first argument the float registers are really

easy you just kind of go in order like xmm0 is the first argument xmm1 is the next argument xmm2

the general purpose uh integer registers they’re a little more complicated you have to remember

their their labels uh you know like the letters have an ordering to it uh suppose for the sake

of argument that we’re going to return a double from this also uh in that case let’s see did i

just mess the formatting up again i think that’s okay um again we’re going to return xmm0

notice how we’re returning xmm0 oh that’s why i spaced it forward notice how we are

forward notice how we are returning xmm0 and we’re also taking xmm0 these float registers tend to be

reused all over the place none of them are designated as callee saved within the abi

so you always have to stash their values somewhere if you’re ever going to make a function call or

anything or a system call the other thing to keep in mind is notice how rsi i still have rsi there

for the second incoming argument you would imagine that rsi is supposed to be the second argument

supposed to be the second argument even if it uh you know comes after a double but that’s not

actually true because the the order i guess like the the ordering of the uh of the registers they

only count against their own class like the float registers the float arguments they only count

against the position of the float and the uh of the float registers and and and the general purpose

they only count against themselves.

What I’m trying to say is that RSI is the second integer argument,

but if you look at the signature, we only have one integer argument, right?

So RSI is not the second integer argument.

It’s actually the first integer argument.

So I’m going to put an RDI there.

You probably can infer that the second float argument should be XMM1 at this point, I hope.

and that’s true if we just say that there’s going to be another double

that this function takes then it’s going to be xmm1

not xmm2 because if you’re just counting the arguments

and you’re sort of grouping the integers with the floats together

you might think well first argument is xmm0 second argument would have been xmm1

third argument would have been xmm2 therefore if I see

a float coming into the third argument position it’ll be xmm2

No, the integers don’t count against the floats and the floats don’t count against the integers.

That’s why RDI is the first argument for integers, even though it’s in the second position,

it’s still the first integer that we see.

And XMM1 is the second float argument that we see.

That’s why it’s XMM1 instead of XMM2, because we’re looking at it in the third position.

So you’re not really looking at, whoops, you’re not looking at overall position.

at position only counting that type of register let me pull open my favorite book to get a little

bit more clarity on this um this book is written by a wonderful professor dr ed jorgensen phd

this book i did not write it ed jorgensen wrote this book it’s called x86 64 assembly language

programming with ubuntu this book can turn you into an expert with yasm assembly so uh

I recommend everybody grab a copy. It’s also free and it’s got a copy left license.

You can see like the license here. But anyway, I wanted to open up this book real fast

just to show you the registers. Okay. I’m going to search for Kali saved so I don’t have to fumble

around the book too long. Kali saved and that brings us to section 12.8.2 register usage.

let’s see callee saved you’ll see rbx is callee saved rbp is callee saved probably shouldn’t

mess with that one too much r12 13 14 15 all callee saved there’s a couple temporary registers

but if you look carefully rdi is designated as the first argument but it should say really

the first integer argument so rdi is the first integer argument that we see that’s why

argument that we see that’s why in all of these examples the first integer argument that we

actually see is rdi so like for function f long a that was the first integer argument

and then in the function g it’s also the first integer argument and then in function h rdi is

the double pointer b because that is the first integer argument that we actually see

so keep that in mind you would just repeat that pattern you know the second integer argument you

second integer argument you see that’s RSI. That’s why RSI is the pointer here because

pointers are integers and the pointer here and we don’t have anything else but if I guess if we

added another you know let’s say a long D then it would be RSI right there. Hopefully that makes

sense and you can you can carry this logic forward for the first argument the second argument the

and then R8 for the fifth argument R9 for the sixth argument and then you can

look for further arguments on the stack if you need more than that but basically

that’s how you count them up and then the float registers are just a lot

easier they always start at zero and they go all the way up to 15 and so I

don’t know maybe I should just copy paste well maybe I’ll start it from

scratch we’ll say dub no let’s let’s mix it up a little bit more we’ll say long

And the long is going to be returned with the RAX.

And I guess I have to space this forward a little bit.

And then if we have a bunch of floats, say double A.

Can I maybe just copy paste this a little bit so I don’t have to do so much typing?

Okay, so we’ll do double A, double B, double C, double D, double E.

and then this is going to be xmm zero why did i put the extra comment there i don’t know

and then we’re going to have xmm one and then we’re going to have xmm two xmm three and so forth

and just to make sure you’re paying attention ask yourself this real fast if i were to insert

z what register would we use for that would it be the one two three four five the fifth argument

would it be uh would it be r8 or would it be something else hopefully you understand now

let’s say we do a character pointer that it would be rdi because that’s the first integer argument

that we actually see all right and then you know to return we would return in rax and then the

return in RAX and then the floats just keep counting notice how it skipped from XMM2 or it

went from XMM2 to XMM3 even though we crossed over an integer argument in between because the

float arguments don’t count against the integers and the ints don’t count against the floats

let’s see I think

well if you want you can look at section 18.2 which just sort of talks about the floating

which just sort of talks about the floating point registers we have 0 through 15 but I don’t think

we really need to do that here I think we pretty much have everything we need to know to to call

on functions with mixed arguments and to have a function within assembly that supports mixed

arguments so again if your C or C++ modules are expecting some kind of signature like this now you

know how to calculate what registers they’re actually going to populate by the time execution

execution jumps into your assembly function.

And if you want to call a C or a C++ function from assembly,

now you know which registers to populate so that the the other function that

you’re calling can receive the right data from you.

Don’t forget about name mangling, which I talked about in another video.

Okay, I think that’s all I really have to say.

This video was pretty short.

Thank you so much for watching.

I hope you learned a little bit of stuff and had a little bit of fun.

I’ll see you in the next video.

make more videos and grow this community so we’ll be able to do more videos longer videos better

videos or just i’ll be able to keep making videos in general so please do do me a kindness and uh

and subscribe you know sometimes i’m sleeping in the middle of the night and i just wake up because

i know somebody subscribed or followed it just wakes me up and i get filled with joy that’s

exactly what happens every single time so 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 just subscribe

and then I’ll just wake up. I promise that’s what will happen. Also, 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,

which I think is also named somewhere at the bottom of this video. And 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. And if you have a suggestion for

clarifications or errata or just future videos that you want to see please leave a comment or

if you just want to say hey what’s up what’s going on you know just send me a comment whatever i also

wake up for those in the middle of the night i get i wake up in a cold sweat and i’m like it would

really it really mean the world to me i would really appreciate it so again thank you so much

for watching this video and um enjoy the cool music as as i fade into the darkness which is

for us all.

Thank you.

Comments

No comments yet. Why don’t you start the discussion?

Leave a Reply