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
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
Category
🤖
TechTranscript
00:00Hey there! Let's talk about instruction formats in Yasm Assembly.
00:12So 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,
00:19it'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.
00:27So the first thing I want to show you is a really simple instruction called INC and we'll put a register there. We'll say RAX.
00:35We want to take whatever value is inside of the RAX register and just increase it by one.
00:41Simple enough, but it's important to understand that this follows a specific format.
00:47The first thing that we put is the name of the instruction that we want to execute.
00:51The second thing we put is an operand. You know, what thing do we want to increase?
00:56We could actually put other types of operands there. We couldn't put an immediate number like just a hard-coded number,
01:02but we could put a memory location if we wanted to and we were careful about it.
01:06So think about instructions as following this sort of format. Let's see.
01:10INST and then a space and then, you know, sometimes instructions have zero operands.
01:16Like there's an instruction called CQO, I think, and it just takes two registers and sort of like lays them out against each other.
01:24But for now, we'll just assume we're going to write instructions that actually do something to named registers or memory locations or whatever.
01:32So the name of the instruction comes first, and then we have an operand.
01:37One or more operands, up to three actually.
01:40So basically, the operands are separated by commas.
01:42So let's say operand one, operand two, operand three.
01:46And most instructions will follow this format.
01:49Then you just have to figure out what the operands do, what the operands are for.
01:53It's easy to tell that the first operand is the thing that will be increased in the increase operand.
02:01But what about the move instruction?
02:03What 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?
02:13I mean, how would you know?
02:14Remember, this is the instruction and this is the first operand.
02:19And then this is the second operand.
02:21There's not three operands in this instruction.
02:24Other instructions have three operands.
02:27The way it works with the move instruction, I hope you understand already at this point,
02:31is that operand two gets placed into operand one.
02:35So when this instruction is finished, then whatever value was inside of RSI is going to be inside of RDI.
02:41So they're actually going to end up being copies of each other.
02:44Some instructions allow you to put immediate, like I could just put the number 89 right here and the number 89 will get loaded into RDI.
02:54So I don't really even need to use a register.
02:56Some instructions, this one in particular also will allow you to place the name of some variable in brackets as the second operand.
03:07And then what will happen is, if you recall, hopefully let me, let me, let me improve this a little bit.
03:14If you recall, you have a data section and you have a text section.
03:20The text section is for your instructions.
03:22In the data section, we could say some variable and we could define this as a data quad word, I guess, and put like, you know, a big giant number inside of there.
03:32And so now we have a variable, a global variable to that module that is sitting in memory somewhere and it's got this value.
03:38So then what we can do is basically say, take the name of that variable, stick it inside of brackets.
03:44And then the move instruction will go grab that number, grab the value associated with that variable and then load that into RDI.
03:52What if we didn't put brackets?
03:56What if we just said load and then some variable?
03:58This is how you place a pointer inside of a register.
04:02Remember all these registers, at least the general purpose registers with this R format, are 64 bit registers.
04:10And in the 64 bit CPUs, that means you could hold a memory location in the register.
04:15So it's pretty convenient.
04:17When 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.
04:24And I would like to fill it up with this data, you know, like let's take eight bytes, reserve it for us.
04:29Then we'll convert all the ones and zeros appropriately so that it ends up equaling that value.
04:34Then when we're done, it'll give us a pointer to that memory location.
04:38So this is really not 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.
04:46All these are actually just pointers.
04:49So 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.
05:05But the moment I put the brackets around it, it will dereference the pointer for me and take the value and then send the value into that.
05:13Hopefully that makes sense.
05:15Okay.
05:16So we've got pointers, dereference pointers, immediates and registers.
05:20That actually went by pretty fast.
05:22I thought this was going to be a long video.
05:25Well, let's look at my favorite book here, the Ubuntu coding book.
05:29Let's see.
05:30Oh, maybe first let's look at the add instruction because I wanted to get something with three operands.
05:36So let's do an instruction with three operands.
05:40I'll say INST and we'll do operand one, operand two, operand three.
05:45So we have this add instruction here where we can just add two integers together.
05:49I could say let's load the value of, you know what, let's do this first with only two.
05:58Yeah.
05:59Cause that'll be more fun.
06:00Let's do a RDI and RSI.
06:03Okay.
06:04So this is, this is legal.
06:07You can have an instruction named add that uses either two or three operands.
06:12A lot of instructions do that usually in the two operand format.
06:16What they're saying is let's do something with both of these values and then store the result
06:21of doing something in the first register.
06:23So for example, it's going to take RDI and add it with RSI, assuming twos compliment integers.
06:31And then it's going to store the result of that addition inside of RDI.
06:34So if you think about it, it's, it's faster to type, but sometimes it might destroy data.
06:40If you didn't actually expect to modify RDI, if you wanted to store the result somewhere
06:45else, but still, you know, add RDI and RSI somewhere, then that wouldn't work.
06:49So let's do the three operand format, operand two, operand three.
06:55So now let's say that we wanted to store in some other register without destroying RDI
07:02after we do the addition.
07:03So we can use the three operand format.
07:05Maybe I'll hit space here a couple of times just to make it a little more interesting.
07:09I guess I probably should have formatted the comment.
07:11Let me try to, no, I guess I can't.
07:14I don't need to space it out.
07:17Well, I could, I could anyway.
07:19So we'll use the add instruction, which is totally valid to use for three operands in
07:24addition to two operands.
07:25And what will happen now is it'll take RDI and add it to RSI and store the result in
07:32R11 in case you wanted to preserve the value of RDI and RSI.
07:36Lots and lots of different instructions with lots and lots of different things that you can do.
07:41Of course, we could put a memory location there.
07:43We could put like an immediate somewhere.
07:45But let me go to my favorite book here.
07:48Whoops, I already have it highlighted on the right section.
07:51So again, I've said this before in my other videos.
07:55This book is called X8664 Assembly Language Programming with Ubuntu by a brilliant doctor.
08:03And I use this book all the time.
08:06I'm not going to say his name because I don't want to accidentally mispronounce it.
08:09I'm pretty sure I know how, but I don't even want to try because I suck at pronouncing things.
08:16I've pronounced my own name wrong on many occasion.
08:21So let's see.
08:22I'm going to click on section seven, the instruction set overview.
08:26And 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.
08:33Like if you see this notation, it means you can put a register as an operand.
08:37If you see this notation, it means that's going to be the source operand.
08:41If you put if you see this notation, it means you can put an immediate at that spot.
08:45So the book just kind of tells you what to expect in terms of notation.
08:48Then if you go down, it starts explaining a bunch of different instructions.
08:52For example, the move instruction that we've just been working with.
08:54Notice how it tells you the sources on the right.
08:57The destination is on the left.
08:59And if we are taking from a memory location, which I probably should have mentioned, let me see.
09:06Did I mention that?
09:07No, I don't think I did.
09:09If 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.
09:20See here we kind of made a bad assumption.
09:25We made the assumption that RDI was a 64 bit register.
09:30That's a good assumption.
09:31But then we also made the assumption that sitting at that pointer is eight bytes of memory.
09:37That's a bad assumption.
09:39Up at the top, we know that when we put DQ for data quad word, then eight bytes are going to get allocated.
09:48But by the time we get down to this instruction, you know, assembly is not very smart.
09:52By the time we get down to this instruction, we can't be sure if that pointer refers to something that is eight bytes or four bytes or two bytes.
09:59We should be able to support loading a number.
10:01Like just as an example, I could lower this number, like let's say with the number 25.
10:09But you know that the number 25 will fit into just a single byte.
10:13It'll also fit into a word, two bytes.
10:15It'll also fit into a 32 bit number, a D word, you know, four bytes.
10:19It'll also fit into a quad word, 64 bits, eight bytes.
10:24So it'll fit in different sizes of data.
10:27So what if you have a memory allocation, like instead of putting DQ, what if we put DB for just data byte?
10:33So just like one byte of memory to put that 25 in, that should work.
10:37But the point is this part of the code doesn't actually know how big the memory location is.
10:43So it doesn't know how many bytes to grab.
10:45Like what if we, what if it just assumed that because we used a 64 bit register, actually, let's go back up here.
10:52Let's change this to a byte, data byte.
10:55So we know that the 25 occupies only one byte.
10:59But here, if we were unlucky, then the assembler might assume, oh, they want to load eight bytes of memory interpreted as a number,
11:08and then put that into a 64 bit register, an eight byte register.
11:12But that probably wouldn't work because we only actually modified one byte to make that 25.
11:18So there's going to be seven other bytes of junk data.
11:22So now we just loaded RDI with some sort of a nonsense value.
11:27And even if it does work, it might not work on every run of the program.
11:30So then you have something which is probably undefined behavior where it's just like you made a bad mistake
11:36and your program's going to work sometimes and maybe some other times not work.
11:40So how do we fix this?
11:42We just specify the size of the memory location or of the bytes that we're going to grab at that memory location.
11:48So 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
11:57and then put that into RDI rather than all the extra junk data.
12:01So if I want to make sure that it understands that I want eight bytes and also to prevent it from refusing to compile,
12:07which it's probably going to do if I don't specify the size,
12:10I'll put keyword to say, yeah, this 25, it's actually a keyword. It occupies eight bytes.
12:16So I want you to load up eight bytes in RAM and interpret all those bytes as just, you know, whatever numbers inside of them.
12:22Pretty sweet. I love going to this book because I was going to forget to say that.
12:27Anyway, just so you know, there's a bunch of instructions that you can look up.
12:32I'm not going to go through all of them, but, you know, typically the leftmost operand
12:37in some sort of a modifying instruction is going to be the destination register or a memory location.
12:44And if you have a two operand instruction, it's probably going to take both operands and do something with them
12:51and then stick the result in the first operand.
12:54And then if you have a three operand instruction, it's probably going to take the rightmost two operands,
12:58do something with them, store the result in the leftmost operand.
13:02But just so you know, this wonderful, wonderful book will tell you exactly what to expect for every type of instruction.
13:10So there's like move here, integer arithmetic.
13:13Oh, yeah, there's the add function or sorry, the add instruction.
13:17And then here's like a bunch of sample code, which is awesome.
13:20And notice how here if we want to increase something that is located at a memory location,
13:25we got to specify the size of the memory.
13:28Again, same problem that we just talked about up above.
13:31Let's see. Did we do that at the beginning?
13:33I don't remember if we did that.
13:35You know, if we have something where it's like if we said increase the RAX register,
13:42the computer knows that RAX is a 64 bit register because the way we typed it, RAX, that implies 64 bits.
13:49If we meant to only use 32 bits of the register, we would type a different set of letters to represent that register.
13:55But if we say I would like you to increase the value sitting in memory at some variable dereferenced,
14:03well, then whoops, it doesn't actually know how many bytes.
14:08If you increase a small value, like if it's if you have one byte and you try to increase it, what if it overflows?
14:18Like, 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,
14:25that's the highest value that a byte can store.
14:28So if we then say let's increase that, the computer is going to, you know, like overflow back down to just zero or not.
14:38What if it actually was a quad word?
14:41The computer didn't understand whether it's supposed to overflow or not overflow.
14:44Do you see what I'm saying?
14:45There's lots of problems that can happen if you don't know the size.
14:48So that just means we have to specify the size.
14:50Anytime we're dealing with memory, we'll say we'll increase a keyword sitting at some variable.
14:56And of course, if you're going to.
14:58I don't know why you'd want to do this, but if you wanted to.
15:00Well, I guess if you're running through a string, if you wanted to increase a pointer value,
15:05then I think you don't have to specify the data size,
15:10although I'm not actually sure if you can change the value of that pointer.
15:13I don't know if it's hard coded.
15:15Usually what I do is I would just move, you know, some kind of a, I would move the pointer.
15:20If we're, if we're using a running pointer to run through like an array of data,
15:23I would load the pointers value into a register.
15:26And then I would just start increasing the register just to make things a little bit easier,
15:29because as I usually try to say, it's way slower to constantly be hitting memory.
15:35Anytime you can possibly keep all of your calculations and algorithms and stuff inside of only registers as long as possible,
15:44then your program will be way, way faster.
15:45So if you're going to run through a bunch of data with a pointer,
15:48probably want to load it up into a register first and then keep increasing the register.
15:51When you finally figure out, you know, everything that's calculated and finished,
15:56then go ahead and save it back to a memory at the very end.
15:59But just to let you know, we've got lots of stuff.
16:03Okay. So there's the add function.
16:05This is the two op version you can see at the top there.
16:08Let's see. Where's the three op version?
16:11Here's somebody honking the horn outside.
16:15Someone, someone's upset with a someone else.
16:19Someone's upset.
16:21Do you ever honk the horn, not angry, but just so that the other driver will think you're angry
16:25and then possibly be a good driver or a better driver later on in their life?
16:30I don't know if that actually works.
16:32I have tried it.
16:33And you do your eyebrows like this, even though you're not upset.
16:39I wonder if they just go home laughing and they're like,
16:42Yeah, you're right. I was ridiculous.
16:44Okay. So I guess I'm going to stop scrolling.
16:47A good coder always reads the documentation and studies ahead and things like that.
16:53I know you were hoping for me to tell you everything in this video,
16:56but there's just not enough time or energy to do that.
16:59I just wanted you to understand how to interpret instruction formats.
17:05I wanted to make that part easy for you,
17:06but all the different instructions that are available to you to multiply,
17:10to add, to increase values, to do all this stuff.
17:13It's all in this nice, wonderful book.
17:16Okay. Anyway, I think I'm going to cut the video.
17:19I hope you enjoyed what you have learned.
17:22I hope you have learned a lot of stuff and had a little bit of fun there.
17:25And I'll see you in the next video.
17:28Hey everybody. Thanks for watching this video again from the bottom of my heart.
17:33I really appreciate it.
17:34I do hope you did learn something and have some fun.
17:37If you could do me a please, a small little favor,
17:40could you please subscribe and follow this channel or these videos
17:44or whatever it is you do on the current social media website that you're looking at right now.
17:48It would really mean the world to me and it'll help make more videos and grow this community.
17:53So we'll be able to do more videos, longer videos, better videos, or just I'll be able to keep making videos in general.
17:59So please do me a kindness and subscribe.
18:03You know, sometimes I'm sleeping in the middle of the night and I just wake up because I know somebody subscribed or followed.
18:09It just wakes me up and I get filled with joy.
18:11That's exactly what happens every single time.
18:13So 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.
18:18Just subscribe and then I'll, I'll just wake up. I promise that's what will happen.
18:22Also, 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,
18:29which I think is also named somewhere at the bottom of this video.
18:32And 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.
18:41And, 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.
18:52Or if you just want to say, Hey, what's up, what's going on, you know, just send me a comment, whatever.
18:56I also wake up for those in the middle of the night.
18:58I get, I wake up in a cold sweat and I'm like, it would really, it really mean the world to me.
19:03I would really appreciate it.
19:04So 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.
19:22Bye.
19:23Bye.
19:52Bye.
19:53Bye.
20:22Bye.
20:52Bye.
20:53Bye.
21:22Bye.
21:23Bye.
21:52Bye.
21:53Bye.
Recommended
23:42
|
Up next
50:14
20:03
21:30
20:46
31:04
0:29
Be the first to comment