Ever stared at “mov rdi, rsi” and wondered WHO goes WHERE?
This 18-minute crash course turns confusion into confidence.
We start with the world’s simplest instruction (inc rax) and level-up to:
- Zero, one, two, and three-operand formats
- Why “mov rdi, 89” and “mov rdi, [someVar]” are NOT the same
- Brackets = dereference, no brackets = pointer
- When ADD destroys your register (and how to stop it)
- The memory-size trap that crashes 90% of beginners
- Byte / word / dword / qword prefixes that save your life
- Pro tip: keep everything in registers until the last microsecond
Code is shown live in Yasm, every line explained like you’re sitting next to me.
No fluff, no 2-hour theory—just the exact mental model you need to read and write assembly tomorrow.
Grab the free PDF cheat-sheet (link in first comment) and code along.
Hit Subscribe—next video we build a complete program from scratch.
Assembly #x86_64 #Yasm #LowLevel
Introduction to Instruction Formats 00:00:00
Simple INC Example 00:00:28
Instruction and Operand Basics 00:00:47
Zero to Three Operands 00:01:14
MOV Instruction Explained 00:02:02
Immediates and Registers 00:02:44
Memory Variables and Pointers 00:03:16
Dereferencing with Brackets 00:05:08
ADD with Two Operands 00:05:32
ADD with Three Operands 00:06:55
Consulting the Ubuntu Book 00:07:45
MOV Source vs Destination 00:08:52
Memory Size Matters 00:09:07
Specifying Data Size 00:11:40
INC on Memory Locations 00:13:19
Why Size Prefixes Prevent Bugs 00:14:08
Performance Tip – Use Registers 00:15:12
Book Recommendation Wrap-up 00:16:04
Thanks for watching!
Find us on other social media here:
- https://www.NeuralLantern.com/social
Please help support us!
- Subscribing + Sharing on Social Media
- Leaving a comment or suggestion
- Subscribing to our Blog
- Watching the main “pinned” video of this channel for offers and extras
Hey there! Let’s talk about instruction formats in Yasm Assembly.
So what am I talking about? Well, if we’re in Yasm Assembly and we’re going to learn how to
use lots and lots of instructions, it’s probably a pretty good idea to understand the general idea
of an instruction and its operands and the things that you can do to it. So the first thing I want
show you is a really simple instruction called inc and we’ll put it we’ll put a
register there we’ll say RAX we want to take whatever value is inside of the RAX
register and just increase it by one simple enough but it’s important to
understand that this is this follows a specific format the first thing that we
put is the name of the instruction that we want to execute second thing we put
is an operand you know what thing do we want to increase we could actually put
We could actually put other types of operands there.
We couldn’t put an immediate number, like just a hard-coded number,
but we could put a memory location if we wanted to, and we were careful about it.
So think about instructions as following this sort of format.
Let’s see, INST, and then a space, and then, you know,
sometimes instructions have zero operands, like there’s an instruction called CQO, I think,
and it just takes two registers and sort of like lays them out against each other.
against each other but for now we’ll just assume we’re going to write instructions that
actually do something to named registers or memory locations or whatever.
So the name of the instruction comes first and then we have an operand.
One or more operands up to three actually.
So basically the operands are separated by commas so we’ll say operand one, operand two,
operand three and most instructions will follow this format.
do what the operands are for it’s easy to tell that the first operand is the
thing that will be increased in the increase operand but what about the move
instruction what if we wanted to move you know one register to another let’s
say RDI to RSI or sorry RDI from RSI or vice versa I mean how would you know
remember this is the instruction and this is the first operand and then this
And then this is the second operand.
There’s not three operands in this instruction.
Other instructions have three operands.
The way it works with the move instruction,
I hope you understand already at this point,
is that operand two gets placed into operand one.
So when this instruction is finished,
then whatever value was inside of RSI is going to be inside of RDI.
So they’re actually going to end up being copies of each other.
Some instructions allow you to put immediates,
like I could just put the number 89 right here and the number 89 will get loaded into RDI so I
don’t really even need to use a register. Some instructions this one in particular also will
allow you to place the name of some variable in brackets as the second operand and then what’ll
happen is if you if you recall hopefully let me let me let me improve this a little bit.
you have a data section and you have a text section.
The text section is for your instructions.
In the data section, we could say some variable
and we could define this as data quad word, I guess,
and put like a big giant number inside of there.
And so now we have a variable, a global variable to that module
that is sitting in memory somewhere and it’s got this value.
So then what we can do is basically say,
take the name of that variable, stick it inside of brackets,
and then the move instruction will go grab that number, grab the value associated with that
variable and then load that into RDI. What if we didn’t put brackets? What if we just said load and
then some variable? This is how you place a pointer inside of a register. Remember all these registers,
at least the general purpose registers with this R format, are 64-bit registers and in the 64-bit
use that means you could hold a memory location in the register so it’s pretty convenient when
when you define a variable up top here what you’re really doing is you’re saying i would like to
allocate eight bytes for a quad word and i would like to fill it up with this data
you know like let’s take eight bytes reserve it for us then we’ll convert all the ones and zeros
appropriately so that it ends up equaling that value then when we’re done it’ll give us a pointer
a normal variable that you usually would think of in C++ where it’s just like the variable is the
variable and not a pointer to something. All these are actually just pointers. So if I load some
variable into RDI I’m actually loading a pointer to RDI which by the way would make it pretty easy
for you to pass a pointer into another function just by loading up RDI with some pointer to you
know some of your data somewhere. But the moment I put the brackets around it it will dereference
it will dereference the pointer for me
and take the value and then send the value into that.
Hopefully that makes sense.
Okay, so we got pointers, dereference pointers,
immediates and registers.
That actually went by pretty fast.
I thought this was gonna be a long video.
Well, let’s look at my favorite book here,
the Ubuntu coding book.
Let’s see.
Oh, maybe first let’s look at the add instruction
because I wanted to get something with three operands.
So let’s do an instruction with three operands.
I’ll say INST and we’ll do operand one, operand two, operand three.
So we have this add instruction here where we can just add two integers together.
I could say let’s load the value of, you know what, let’s do this first with only two.
Yeah, because that’ll be more fun.
Let’s do RDI and RSI.
Okay, so this is legal.
You can have an instruction named add that uses either two or three operands.
A lot of instructions do that.
Usually in the two operand format, what they’re saying is,
let’s do something with both of these values and then store the result
of doing something in the first register.
So for example, it’s going to take RDI and add it with RSI,
assuming two’s complement integers.
store the result of that addition inside of RDI. So if you think about it, it’s faster to type,
but sometimes it might destroy data if you didn’t actually expect to modify RDI.
If you wanted to store the result somewhere else, but still add RDI and RSI somewhere,
then that wouldn’t work. So let’s do the three operand format, operand two, operand three.
So now let’s say that we wanted to store in some other register without destroying
RDI after we do the addition. So we can use the three operand format. Maybe I’ll
hit space here a couple times just to make it a little more interesting. I
guess I probably should have formatted the comment. Let me try to… No I guess I
can’t. I don’t need to space it out. Well I could. I could anyway. So we’ll use the
add instruction which is totally valid to use for three operands in addition to
two operands. And what will happen now is it’ll take RDI and add it to RSI
and add it to RSI and store the result in R11 in case you wanted to preserve the value of RDI and
RSI. Lots and lots of different instructions with lots and lots of different things that you can do.
Of course, we could put a memory location there. We could put like an immediate somewhere.
But let me go to my favorite book here. Whoops, I already have it highlighted on the right section.
x86 64 assembly language programming with Ubuntu by a brilliant doctor and I
use his book all the time I’m not gonna say his name because I don’t want to
accidentally mispronounce it I’m pretty sure I know how but I don’t even want to
try because I suck at pronouncing things I’ve pronounced my own name wrong on
many occasion so let’s see I’m gonna click on section 7 the instruction set
the instruction set overview and basically you know it kind of goes over the fact that oh you
know we can put registers as operands and we can do some certain things like if you see this
notation it means you can put a register as an operand if you see this notation it means that’s
going to be the source operand if you put if you see this notation it means you can put an immediate
at that spot so the book just kind of tells you what to expect in terms of notation then if you
go down it starts explaining a bunch of different instructions for example the move instruction
instructions. For example, the move instruction that we’ve just been working with. Notice how it
tells you the source is on the right, the destination is on the left. And if we are taking
from a memory location, which I probably should have mentioned, let me see, did I mention that?
No, I don’t think I did. If we’re taking from a memory location, it’s important to understand that
the data size of the memory locations data and the register might actually be different. See,
different. See here we kind of made a bad assumption. We made the assumption that RDI
was a 64-bit register. That’s a good assumption. But then we also made the assumption that sitting
at that pointer is eight bytes of memory. That’s a bad assumption. Up at the top, we know that
when we put DQ for data quad word, then eight bytes are going to get allocated. But by the time we
But by the time we get down to this instruction, you know assembly is not very smart.
By the time we get down to this instruction, we can’t be sure if that pointer refers to
something that is 8 bytes or 4 bytes or 2 bytes.
We should be able to support loading a number.
Like just as an example, I could lower this number, like let’s say with the number 25,
but you know that the number 25 will fit into just a single byte.
It’ll also fit into a word, 2 bytes.
32 bit number, a D word, you know, four bytes.
It’ll also fit into a quad word, 64 bits, eight bytes.
So it’ll fit in different sizes of data.
So what if you have a memory allocation,
like instead of putting DQ,
what if we put DB for just data byte?
So just like one byte of memory to put that 25 in,
that should work.
But the point is this part of the code
doesn’t actually know how big the memory location is.
So it doesn’t know how many bytes to grab.
many bytes to grab like what if we what if it just assumed that because we used a 64-bit register
actually let’s go back up here let’s change this to a byte data byte so we know that the 25 occupies
only one byte but here if we were unlucky then the assembler might assume oh they want to load
eight bytes of memory interpreted as a number and then put that into a 64-bit register an eight
But that probably wouldn’t work because we only actually modified one byte to make that 25.
So there’s going to be seven other bytes of junk data.
So now we just loaded RDI with some sort of a nonsense value.
And even if it does work, it might not work on every run of the program.
So then you have something which is probably undefined behavior,
where it’s just like you made a bad mistake and your program’s going to work sometimes
and maybe some other times not work.
So how do we fix this?
So how do we fix this? We just specify the size of the memory location or of
the bytes that we’re going to grab at that memory location. So if I just put
the word byte in front, now the assembler knows that I only want to grab
one byte and interpret that as a number and then put that into RDI rather than
all the extra junk data. So if I want to make sure that it understands that I want
eight bytes and also to prevent it from refusing to compile, which it’s probably
going to do if i don’t specify the size i’ll put q word to say yeah this 25 it’s uh it’s actually
a q word it occupies eight bytes so i want you to load up eight bytes in ram and interpret all
those bytes as just you know whatever numbers inside of them pretty sweet i love going to this
book because i was going to forget to say that anyway just so you know there’s a bunch of
instructions that you can look up i’m not going to go through all of them but um you know typically
Leftmost operand in some sort of a modifying instruction is going to be the destination
register or memory location.
And if you have a two operand instruction, it’s probably going to take both operands
and do something with them and then stick the result in the first operand.
And then if you have a three operand instruction, it’s probably going to take the rightmost
two operands, do something with them, store the result in the leftmost operand.
wonderful, wonderful book will tell you exactly what to expect for every type of instruction.
So there’s like move here, integer arithmetic. Oh yeah, there’s the add function or sorry,
the add instruction. And then here’s like a bunch of sample code, which is awesome.
And notice how here, if we want to increase something that is located at a memory location,
we got to specify the size of the memory. Again, same problem that we just talked about up above.
Did we do that at the beginning?
I don’t remember if we did that.
You know, if we have something where it’s like,
if we said increase the RAX register,
the computer knows that RAX is a 64-bit register
because the way we typed it, RAX, that implies 64 bits.
If we meant to only use 32 bits of the register,
we would type a different, you know,
set of letters to represent that register.
But if we say, I would like you to increase
the value sitting in memory at some variable,
sitting in memory at some variable dereferenced, well then whoops,
it doesn’t actually know how many bytes.
If you increase a small
value, like if it’s if you have one byte and you try to increase it,
what if it overflows?
Like, for example, if we had a one byte, if we had one byte of data here
and we had the number, let’s say 255 already, that’s the highest value that a
So if we then say let’s increase that,
the computer is going to, you know, like overflow back down to just zero or not.
What if it actually was a quad word?
The computer didn’t understand whether it’s supposed to overflow or not overflow.
Do you see what I’m saying?
There’s lots of problems that can happen if you don’t know the size.
So that just means we have to specify the size.
Anytime we’re dealing with memory, we’ll say we’ll increase a keyword sitting at some
variable. And of course, if you’re going to
and of course if you’re gonna i don’t know why you’d want to do this but if you wanted to well
i guess if you’re running through a string if you wanted to increase a pointer value uh then i think
you don’t have to specify the data size although i’m not actually sure if you can change the value
of that pointer i don’t know if it’s hard coded usually what i do is i would just move you know
some kind of a i would move the pointer if we’re if we’re using a running pointer to run through
I would load the pointers value into a register and then I would just start increasing the
register just to make things a little bit easier because as I usually try to say it’s
way slower to constantly be hitting memory.
Anytime you can possibly keep all of your calculations and algorithms and stuff inside
of only registers as long as possible, then your program will be way, way faster.
So if you’re going to run through a bunch of data with a pointer, probably want to load
it up into a register first and then keep increasing the register.
When you finally figure out, you know, everything that’s calculated and finished,
then go ahead and save it back to memory at the very end.
But just to let you know, we’ve got lots of stuff.
Okay, so there’s the add function.
This is the two op version.
You can see at the top there.
Let’s see, where’s the three op version?
Here’s somebody honking the horn outside.
Someone’s upset with someone else.
Someone’s upset.
Someone’s upset. Do you ever honk the horn not angry, but just so that the other driver will think you’re angry and
Then possibly be a good driver or a better driver later on in their life. I don’t know if that actually works. I have tried it
And you do your eyebrows like this
Even though you’re not upset
I wonder if they just go home laughing and they’re like, yeah, you’re right. I was ridiculous
Okay, so I guess I’m gonna stop scrolling
a
A good coder always reads the documentation and studies ahead and things like that
I know you were hoping for me to tell you everything in this video, but there’s just not enough time or energy to do that
I just wanted you to understand
How how to how to interpret instruction formats?
I wanted to make that part easy for you
but all the different instructions that are available to you to multiply to add to increase values to do all this stuff
It’s all in this nice wonderful book
okay anyway I think I’m gonna cut the video I hope you enjoyed what you have
learned I hope you have learned a lot of stuff and had a little bit of fun there
and I’ll see you in the next video hey everybody thanks for watching this video
again from the bottom of my heart I really appreciate it I do hope you did
learn something and have some fun if you could do me a please a small little
favor could you please subscribe and follow this channel or these videos or
or whatever it is you do on the current social media website that you’re looking at right now.
It would really mean the world to me and it’ll help 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 me a kindness 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.
every single time so you could do it as a nice favor to me or you could you control me if you
want to just wake me up in the middle of the night just subscribe and then i’ll i’ll just wake up i
promise that’s what will happen also uh 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
all that good stuff and 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 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
and enjoy the cool music as I fade into the darkness which is coming for us all.
Thank you.

