- 2 days ago
Want to actually understand how signed integer multiplication works at the CPU level? In this straight-to-the-point x86-64 assembly tutorial we dive into the IMUL instruction - the proper way to multiply signed integers in YASM/NASM on Linux.
We cover:
* The difference between unsigned (MUL) and signed (IMUL) multiplication
* Two-operand vs three-operand IMUL forms
* Multiplying immediate values vs global variables
* Loading values into registers (mov) and performing fast multiplication
* Basic addition with ADD and INC
* Full working example that prints results so you can see it in action
* Why you should respect the ABI and save callee-saved registers (R12-R15)
Everything is built with YASM on Ubuntu, linked with a tiny C driver, and run instantly. No fluff, just real assembly code you can copy and run right now.
Code on screen, calculator verification, and clear explanation of every line. Perfect if you're learning low-level programming, reverse engineering, or just want to know what really happens when you write a = b * c; in C.
Introduction to Integer Arithmetic 00:00:00
Recommended Book and Resources 00:00:39
Instruction Set Overview 00:01:17
Addition Instruction (ADD) 00:01:43
Unsigned vs Signed Multiplication 00:02:20
Signed Multiplication with IMUL 00:03:05
IMUL Three-Operand Form 00:03:40
IMUL Two-Operand Form 00:04:12
Squaring with IMUL 00:04:50
Setting Up the Sample Program 00:05:08
Data Section and Strings 00:06:13
Text Section and External Functions 00:06:58
Math Function Entry Point 00:08:01
Multiply Test Function Setup 00:08:42
Multiplying Immediate Values 00:09:48
Printing the Immediate Result 00:10:21
Running and Verifying Immediates 00:12:53
Multiplying Global Variables 00:13:49
Loading Globals into Registers 00:14:07
IMUL with Globals Demo 00:14:37
Addition with INC and ADD 00:15:36
Final Results and Verification 00:17:09
Wrap-Up and Closing 00:17:22
Outro and Subscribe Request 00:17:44
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
We cover:
* The difference between unsigned (MUL) and signed (IMUL) multiplication
* Two-operand vs three-operand IMUL forms
* Multiplying immediate values vs global variables
* Loading values into registers (mov) and performing fast multiplication
* Basic addition with ADD and INC
* Full working example that prints results so you can see it in action
* Why you should respect the ABI and save callee-saved registers (R12-R15)
Everything is built with YASM on Ubuntu, linked with a tiny C driver, and run instantly. No fluff, just real assembly code you can copy and run right now.
Code on screen, calculator verification, and clear explanation of every line. Perfect if you're learning low-level programming, reverse engineering, or just want to know what really happens when you write a = b * c; in C.
Introduction to Integer Arithmetic 00:00:00
Recommended Book and Resources 00:00:39
Instruction Set Overview 00:01:17
Addition Instruction (ADD) 00:01:43
Unsigned vs Signed Multiplication 00:02:20
Signed Multiplication with IMUL 00:03:05
IMUL Three-Operand Form 00:03:40
IMUL Two-Operand Form 00:04:12
Squaring with IMUL 00:04:50
Setting Up the Sample Program 00:05:08
Data Section and Strings 00:06:13
Text Section and External Functions 00:06:58
Math Function Entry Point 00:08:01
Multiply Test Function Setup 00:08:42
Multiplying Immediate Values 00:09:48
Printing the Immediate Result 00:10:21
Running and Verifying Immediates 00:12:53
Multiplying Global Variables 00:13:49
Loading Globals into Registers 00:14:07
IMUL with Globals Demo 00:14:37
Addition with INC and ADD 00:15:36
Final Results and Verification 00:17:09
Wrap-Up and Closing 00:17:22
Outro and Subscribe Request 00:17:44
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:00okay
00:03hey everybody in this video i'd like to talk to you a little bit about
00:07integer arithmetic in yasm assembly on an x86-64 system
00:18so what am i talking about well integer arithmetic i want to take integers and i want to add them
00:22together multiply them together whatever this video is mostly going to focus on signed integer
00:27multiplication but i'm going to briefly skim through unsigned integer multiplication and also
00:33addition and anyway so for starters let me go up to this the top of this book here that i've got
00:40i'm going to show you pages from a book that i really really love i mention it in a lot of my
00:44other videos it's called x86-64 assembly language programming with ubuntu and it is written by a
00:50brilliant doctor professor who is just interested in everyone learning this is an open source book
00:56you can get yourself a copy for free just look that title and name up you can find his website
01:02you can grab a copy and you too can become an assembly expert just by reading this book honestly
01:06this book has everything that you really need to to really level yourself off level yourself up well
01:12beyond i think the master's level of college probably not as much as the person who wrote the book but
01:20you never know anyway let me uh uh collapse all that i want to go down to section seven here
01:28and uh it's called instruction set overview so here you can have like an overview of like
01:32all different types of instructions but i'm going to focus on the integer arithmetic instruction so i'm
01:37going to go to 7.5 notice how the first section in here is addition i'm not going to give you an
01:44addition example because it's just too easy you pretty much use just use the add instruction
01:48and then you have a source and destination operand actually dest comma source
01:53in x86 yasm assembly it's pretty much the destination is the first operand so uh that's
01:59kind of implied usually when you have just like a two operand instruction now we could add using three
02:04operands and the the first one would be the destination and then the other two would be the
02:09sources but i'm going to scroll down past that uh to the integer multiplication section
02:157.5.3 at least as of the version that i'm using unsigned multiplication is a little tricky
02:23and you kind of have to decide what data size you're going to go with and then you use the
02:29instruction uh and then you end up with some some uh some answers that are spread across multiple
02:37registers i'm going to eventually make other videos where i can talk to you about how to manipulate
02:42multiple registers or at least know that they're there like edx and eax those are definitely not
02:4864-bit registers so if we were clever we could just sort of manipulate those so that the whole answer
02:53showed up um on one single 64-bit register if we wanted to but just know you can multiply unsigned
03:01integers it's a little bit more complicated than signed integers so in this video i'm just going to
03:05talk about signed integers let's see so signed integer multiplication so in order that's a section
03:127.5.3.2 if you want to multiply two integers and they're signed meaning they have a plus or a minus
03:18sign meaning they're designated as either positive or negative rather than not designated at all which
03:24would usually just mean positive you can use i'm all as an instruction and uh well you can just
03:33provide you know one operand two operands or three operands let's do the three operand version first
03:41because that's probably the easiest to understand right off the bat so uh we would take a number
03:46that's sitting in a register and then we would multiply it by some immediate notice how imm is sitting
03:51here uh the result of multiplying a register by some number would just go into the destination operand
03:57so that means you'd put a register here you'd put a register here you'd put a register here you'd put
04:01an immediate here uh in one instruction then you'd have some sort of an answer on what these two
04:07numbers were multiplied against each other if you use the two operand version then you're allowed to
04:13specify a register for the destination and a register for the source but uh notice how the destination gets
04:22overwritten here so uh you know it's going to multiply this number by this number and then just store the
04:28result in the first register so you will kind of overwrite something it's maybe more convenient for
04:36you to use the three operand version if you only want to multiply by an immediate but uh you know anyway
04:42and then for the let's see let's see i think you can square a number just by specifying its source here
04:52it'll multiply a number by itself and then um let me just go down a little bit i'm starting to get lost
04:59in this book let me go down a little bit oh i guess that's all we really had to say okay so let me show
05:07you a sample program that i've prepared so that we can multiply okay sample program i think i need to
05:15rehearse myself a little bit more before i record videos anyway i've got this uh empty source code
05:22file here keep in mind that um well i don't need that keep in mind that i have a sample program here
05:28already i'm not going to really focus on the contents of it uh because this is not what did i do wrong
05:33here main and math is main empty no no where's my make file oh i forgot to open it this is not a video
05:42about make files or hybrid programs or anything like that that's covered in my other videos so
05:46i'm just going to say hey i've got a make file that compiles my assembly source code and then i've got
05:51a driver c source code file which its entire job is just to have the main entry point because i'm
05:57linking against the gcc libraries and then its job is just a call on a math function which sits in my
06:03assembly module uh so now my assembly module is blank what should we do first i'm going to copy paste from
06:09my solution here just a bunch of strings so i've got a data section then i'm going to get set up
06:17this is not a video about the basics of assembly programming see my other videos but for now i'm
06:22just going to say well i've got a bunch of strings i'm going to say the result of multiplying immediates
06:27is this the result of multiplying globals is that we're just going to do a couple of multiplications
06:32and then see the results okay so then a couple more variables before we're finished is
06:42i'm going to now say that we have a system call for system right which is not what this video is about
06:49see my other videos for system calls same thing for file descriptors it's there i'm not going to
06:53explain it too much i'm just going to print to standard output and then uh from this program we're
06:58going to i'm going to return just an integer for whatever reason i'm just saving it as a variable
07:03and then we want to multiply some integers so i'm storing two integers in the global section you know
07:08still inside of the dot data section so that's these are going to be global variables they're going
07:13to be both be quad words so i can load up into quad registers or quad word registers and now i'm ready
07:20to start my text section so the first thing that i'm going to do is just you know say here we go this is
07:26the text section that's where all of our instructions go and then i'm going to name two external symbols
07:34don't worry about these symbols they are not the point of this video but you know i have a little
07:38library that i wrote that helps me print and and take input from the user i'm going to print an integer
07:46i'm going to take an input from the from the user so don't worry about that that's not the point of this
07:51video really i just want to make it so that when i demo i can just easily type in an
07:55integer and then just print it to the user so let's look at our main entry point here
08:01remember the driver calls on a function called math so i'm just going to make an entry point
08:06called math mark it as global so the driver can call on it and then i'm gonna whoops why did i put
08:12load here do i'm gonna put i'm gonna say do it right there let's do it i'm just going to call in
08:19a function i wrote called multiply test kind of pointless if you think about the fact that uh
08:23there's like no code in the main function here but that's the way i like to do it when we're
08:27done we're just going to return our return value that's already been defined and so now i'm ready
08:32to start setting up our multiply test maybe i'll just copy paste the header here and i'll say
08:41this is going to be a label called multiply test because i'm going to call on it and try to use it
08:46like a function i'm going to put a return instruction at the very end so now it really is a function
08:52i'm going to use these registers so i'm going to use r12 r13 r14 and r15 to hold
08:59temporary immediates and globals just for multiplication so i'm basically going to be
09:04using the registers to hold my data and because i'm going to use all of those registers remember you
09:11have to respect the abi so that means we have to have a push pop pair on all of those registers
09:17because they're designated as callee saved if if anyone calls on your functions and you're not
09:24respecting the abi then you're probably about to crash the program in some way or even if you are
09:29the only person who writes any code that your code calls on or gets called from you're probably still
09:35going to regret not not respecting the abi eventually when you forget what's going on
09:38anyway so let's multiply some immediates first thing i'm going to do here is i'm going to say
09:46let's take 233 and move it into r12 because that's where we're going to hold some temporary
09:51immediates and then the number 256 put that into r13 and then i'm going to use the imol instruction
09:58to just multiply those two values together because this is the two operand version of that instruction
10:04the result will also be stored in r12 so that means 233 will be erased from r12 and the answer
10:11will be in r12 so then i'm going to prefix the results for the immediate because i like my programs
10:19to be pretty i'm not just going to print the numbers and then hope i can remember which number
10:23comes first that's usually a huge mistake if you're trying to debug something even a little bit
10:27complicated so i'm going to print my string which i'm calling the immediate prefix and if you look back
10:34up at the top right here it's just going to say the result of multiplying immediates is and then
10:39it's going to put three asterisks and then i'm going to print the actual result and then the suffix
10:45is just going to be three more asterisks so we should basically see um the results surrounded by asterisks
10:52so i'm doing that and then i'm going to use my library to call a special printing function so that i can
10:59just print to the result so r12 is where the result of the multiplication is i'm going to give that as
11:05the first argument which is the rdi register if we're talking about integers and then i'm just going
11:10to call my function that'll print for me and then i'm going to print the suffix
11:17so the suffix is just that other string we talked about just it trails with asterisks
11:22i'm then going to call on a custom function called crlf all that's going to do is just print a new line i
11:26don't know why i do that i could easily put that into the string but it's more fun to call functions
11:32although to be fair every time you call a function you are jumping to an instruction elsewhere and so
11:38the cpu does pay a penalty so if you're trying to write programs for high performance you might not
11:43want to do that anyway so this is pretty fast because i'm really just using an immediate and then
11:50i'm loading it into a register i'm not actually touching global memory so this should be a lightning
11:54fast multiplication operation let's see if this actually works if i didn't screw this up whoops
11:59what did i what did i do there oh no i have too many videos now
12:08gosh okay clear and make run
12:14oh what have i done undefined symbols crlf did i forget oh i forgot to copy paste my crlf function
12:20yeah so again don't worry about crlf all i'm doing is just printing a new line carriage return it's just
12:26you know this is from another example where i was trying to prove to somebody you need to preserve
12:31registers and respect the abi so don't even worry about that let me let me get rid of that
12:39um you know what i'm going to leave it as is because if i take that out then i have to take the time
12:45to remove the push pop pair because there's no point at that i'm doing that if i'm not
12:50messing with those registers forget about that it's not part of this video
12:54anyway i'm going to run the program again and you can see that the result of multiplying
12:59immediates is and so this whole string right here was my prefix so again not really the point of this
13:04video and then this is the result of multiplying those two different numbers and then the suffix with
13:09the stars after so let me just prove this to you where's the dang calculator oh man
13:15i need to work on my icons like i just did something screwy and i have like no good icons anymore
13:21on this virtual machine so we were going to multiply 233 by whoops by what was it 256
13:31result is 5 9 6 4 8 and you can see that's on the screen 5 9 6 4 8 so we have successfully multiplied
13:37signed integers and since they're signed we could multiply negative numbers if we wanted to i'm not going
13:42to here but you can now the next thing let's try is let's multiply uh stuff sitting in global memory
13:53okay so i'm just going to copy this um where the heck is it okay so remember at the top we made two
14:01global integers we said integer a is equal to 233 and then 256 those were the same numbers that we just
14:09multiplied so we should probably get the same result if we're lucky so i'm saying i'm going to move both
14:16of these into registers so i'm going to move a into r14 and i'm going to move b into r15 just to prove to
14:23that we can and then i'm going to multiply them with the same instruction we did before the result is
14:30going to go into r14 so let's see i'm going to print the prefix real fast here same kind of concept that we
14:41talked about before there's just going to be a prefix before the result and then i'm actually going to
14:47print the result with this line right here or these lines i'm just going to print r14 which is holding
14:53the result at this point and uh hey we can trust that r14 wasn't killed by the system call because
15:00the system call respects the abi and then i'm going to print my suffix right here and then a crlf
15:08and uh that's basically the idea let's just double check here that we get the same result twice
15:13make run notice how it prints the same result twice once with globals once with immediates
15:20so if you were wondering before this video how to multiply immediates or how to multiply
15:24globals well there you go just put them into registers first and then call imol pretty fast
15:30let's just do one other thing for fun i'm going to let's see add one number to r14 so to the
15:39uh result of the multiplication and then i'm going to add five to it just to prove to you that we can
15:45increase an integer by one and we can also um just sort of like add two integers together so before we
15:52print it now before we do the prefix extra stuff just for fun so here i'm going to increase r14 and
16:04i'm going to say that uh it is a q word i guess that's implied already because r14 is considered
16:10a 64-bit uh register but if we wanted to increase i don't know just for the sake of argument if we
16:16wanted to like increase this right here let me just show you real fast how we do it you would say
16:20increase q word and then name the integer in global memory so in global memory the system doesn't really
16:27know by default if it's a one byte integer a two byte integer or four or eight so you just have to specify
16:32the data size so it knows which inner integers to look at when it's considering what the original
16:37value is and uh how to overflow and when to overflow but you know just for fun i'm putting that in
16:43here so it's going to increase the result by one and then it's going to increase the result by five
16:48and it's going to do that using the addition instruction so we're going to add r14 with five we
16:54can put an immediate there and the result is going to be stored in r14 so basically r14 is equal to
17:00r14 plus five and so overall when we add those two things in there the second result should now be
17:07about six higher than the first result so if you kind of look at this right here we have 648
17:13and then we have 644 which is six numbers higher than the original result so these are the basics of
17:20integer arithmetic with signed multiplication and addition um i think that's all i really wanted to
17:28show you yeah okay so i hope you learned a little bit of stuff from this video i hope you had a
17:32little bit of fun come back i'll see you in the next video and um happy coding hey everybody thanks
17:41for watching this video again from the bottom of my heart i really appreciate it i do hope you did
17:45learn something and have some fun uh if you could do me a please a small little favor could you please
17:51subscribe and follow uh this channel or these videos or whatever it is you do on the current social
17:56media website that you're looking at right now um it would really mean the world to me and it'll help
18:01make more videos and grow this community so we'll be able to do more videos longer videos better videos
18:07or just i'll be able to keep making videos in general so please do do me a kindness and uh and
18:13subscribe you know sometimes i'm sleeping in the middle of the night and i just wake up because i
18:17know somebody subscribed or followed it just wakes me up and i get filled with joy that's exactly what
18:22happens every single time so you could do it as a nice favor to me or you could you could troll me
18:26if you want to just wake me up in the middle of the night just subscribe and then i'll i'll just wake
18:30up i promise that's what will happen also uh if you look at the middle of the screen right now you
18:36should see a qr code which you can scan in order to go to the website which i think is also named
18:41somewhere at the bottom of this video and it'll take you to my main website where you can just kind of
18:45like see all the videos i published and the services and tutorials and things that i offer and all that good
18:51stuff and uh if you have a suggestion for uh uh clarifications or errata or just future videos
19:00that you want to see please leave a comment or if you just want to say hey what's up what's going on
19:04you know just send me a comment whatever i also wake up for those in the middle of the night i get
19:09i wake up in a cold sweat and i'm like it would really it really mean the world to me i would really
19:14appreciate it so again thank you so much for watching this video and um enjoy the cool music
19:22as as i fade into the darkness which is coming for us all
19:34so
19:40so
19:44so
Be the first to comment