x86-64 Assembly: Signed Integer Multiplication and Addition with IMUL & ADD (YASM on Ubuntu Linux)

x86-64 Assembly: Signed Integer Multiplication and Addition with IMUL & ADD (YASM on Ubuntu Linux)

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

okay

hey everybody in this video i’d like to talk to you a little bit about

integer arithmetic in yasm assembly on an x86-64 system

so what am i talking about well integer arithmetic i want to take integers and i want to add them

together multiply them together whatever this video is mostly going to focus on signed integer

but I’m going to briefly skim through unsigned integer multiplication and also

addition and anyway so for starters let me go up to this the top of this book

here that I’ve got I’m going to show you pages from a book that I really really

love I mentioned it in a lot of my other videos it’s called x86 64 assembly

language programming with Ubuntu and it is written by a brilliant doctor

professor who is just interested in everyone learning this is an open source

you can get yourself a copy for free just look that title and name up you can find his website

you can grab a copy and you too can become an assembly expert just by reading this book

honestly this book has everything that you really need to to really level yourself off

level yourself up well beyond i think the master’s level of college probably

not as much as the person who wrote the book but you never know anyway let me uh

I want to go down to section 7 here and it’s called instruction set overview.

So here you can have like an overview of like all different types of instructions, but I’m

going to focus on the integer arithmetic instructions.

So I’m going to go to 7.5.

Notice how the first section in here is addition.

I’m not going to give you an addition example because it’s just too easy.

You pretty much use just use the add instruction and then you have a source and destination

comma source in x86 yasm assembly it’s pretty much the destination is the first operand so uh

that’s kind of implied usually when you have just like a two operand instruction now we could add

using three operands and the the first one would be the destination and then the other two would

be the sources but i’m going to scroll down past that to the integer multiplication section 7.5.3

unsigned multiplication is a little tricky and

You kind of have to decide what data size you’re going to go with and then you use the instruction

uh, and then you end up with some some uh, some answers that are spread across multiple registers

I’m going to eventually make other videos where I can talk to you about how to manipulate multiple registers or at least know that they’re there like

not 64-bit registers so if we were clever we could just sort of manipulate those so that

the whole answer showed up on one single 64-bit register if we wanted to but just know you can

multiply unsigned integers it’s a little bit more complicated than signed integers so in this video

i’m just going to talk about signed integers let’s see so signed integer multiplication

so in order that’s a section 7.5.3.2 if you want to multiply two integers and they’re signed

and they’re signed meaning they have a plus or a minus sign meaning they’re designated as either

positive or negative rather than not designated at all which would usually just mean positive

you can use imall as an instruction and well you can just provide you know one operand two operands

or three operands let’s do the three operand version first because that’s probably the easiest

So we would take a number that’s sitting in a register and then we would multiply it by some immediate.

Notice how IMM is sitting here.

The result of multiplying a register by some number would just go into the destination operand.

So that means you’d put a register here.

You’d put a register here.

You’d put an immediate here in one instruction.

Then you’d have some sort of an answer on what these two numbers were multiplied against each other.

then you’re allowed to specify a register for the destination and a register for the source.

But notice how the destination gets overwritten here.

So, you know, it’s going to multiply this number by this number

and then just store the result in the first register.

So you will kind of overwrite something.

It’s maybe more convenient for you to use the three operand version

if you only want to multiply by an immediate.

But, you know, anyway, and then for the, let’s see, let’s see, I think you can square a number

just by specifying its source here.

It’ll multiply a number by itself.

And then let me just go down a little bit.

I’m starting to get lost in this book.

Let me go down a little bit.

Well, I guess that’s all we really had to say.

Okay, so let me show you a sample program that I’ve prepared.

that I’ve prepared so that we can multiply. Okay, sample program. I think I need to rehearse myself

a little bit more before I record videos. Anyway, I’ve got this empty source code file here. Keep in

mind that I don’t need that. Keep in mind that I have a sample program here already. I’m not going

to really focus on the contents of it because this is not what did I do wrong here? Main and math.

main empty no no where’s my make file oh I forgot to open it this is not a video

about make files or hybrid programs or anything like that that’s covered in my

other videos so I’m just gonna say hey I’ve got a make file that compiles my

assembly source code and then I’ve got a driver C source code file which its

entire job is just to have the main entry point because I’m linking against

the GCC libraries and then its job is just a call on a math function which

So now my assembly module is blank.

What should we do?

First I’m going to copy paste from my solution here, just a bunch of strings.

So I’ve got a data section that I’m going to get set up.

This is not a video about the basics of assembly programming.

See my other videos, but for now I’m just going to say, well, I’ve got a bunch of strings.

I’m going to say the result of multiplying immediates is this, the result of multiplying

globals is that.

multiplications and then see the results. Okay, so then a couple more variables

before we’re finished is I’m gonna now say that we have a system call for

system right which is not what this video is about. See my other videos for

system calls. Same thing for file descriptors it’s there I’m not gonna

explain it too much I’m just gonna print a standard output and then from this

program we’re gonna I’m gonna return just an integer for whatever reason I’m

for whatever reason. I’m just saving it as a variable. And then we want to multiply some

integers. So I’m storing two integers in the global section, you know, still inside of the

dot data section. So that’s, these are going to be global variables. They’re going to be both

be quad words. So I can load up into a quad registers or quad word registers. And now I’m

ready to start my text section. So the first thing that I’m going to do is just, you know,

that’s where all of our instructions go and then I’m going to name two external

symbols don’t worry about these symbols they are not the point of this video but

you know I have a little library that I wrote that helps me print and and take

input from the user I’m gonna print an integer I’m gonna take an input from the

from the user so don’t worry about that that’s not the point of this video

really I just want to make it so that when I demo I can just easily type in an

and then just print it to the user.

So let’s look at our main entry point here.

Remember the driver calls on a function called math.

So I’m just gonna make an entry point called math,

mark it as global so the driver can call on it.

And then I’m gonna, whoops, why did I put load here?

Do, I’m gonna put, I’m gonna say do it right there.

Let’s do it.

I’m just gonna call on a function I wrote

called multiply test, kind of pointless

if you think about the fact that there’s like no code

in the main function here.

like no code in the main function here but that’s the way i like to do it when we’re done we’re just

going to return our return value that’s already been defined and so now i’m ready to start setting

up our multiply test maybe i’ll just copy paste the header here and i’ll say this is going to be

a label called multiply test because i’m going to call on it and try to use it like a function

i’m going to put a return instruction at the very end so now it really is a function

I’m going to use these registers.

So I’m going to use R12, R13, R14, and R15 to hold temporary immediates and globals

just for multiplication.

So I’m basically going to be using the registers to hold my data.

And because I’m going to use all of those registers, remember you have to respect the

ABI.

So that means we have to have a push pop pair on all of those registers because they’re

designated as callee saved.

saved if anyone calls on your functions and you’re not respecting the abi then you’re probably about

to crash the program in some way or even if you are the only person who writes any code that your

code calls on or gets called from you’re probably still going to regret not respecting the abi

eventually when you forget what’s going on anyway so let’s multiply some immediates first thing i’m

and move it into R12 because that’s where we’re going to hold some temporary

immediates and then the number 256 put that into R13 and then I’m going to use

the I’m all instruction to just multiply those two values together because this

is the two operand version of that instruction the result will also be

stored in R12 so that means 233 will be erased from R12 and the answer that will

the results for the immediate because I like my programs to be pretty. I’m not just going to print

the numbers and then hope I can remember which number comes first. That’s usually a huge mistake

if you’re trying to debug something even a little bit complicated. So I’m going to print my string,

which I’m calling the immediate prefix. And if you look back up at the top right here,

it’s just going to say the result of multiplying immediates is, and then it’s going to put three

asterisks. And then I’m going to print the actual result. And then the suffix is just going to be

And then the suffix is just going to be three more asterisks.

So we should basically see the results surrounded by asterisks.

So I’m doing that.

And then I’m going to use my library

to call a special printing function

so that I can just print to the result.

So R12 is where the result of the multiplication is.

I’m going to give that as the first argument,

which is the RDI register, if we’re talking about integers.

And then I’m just going to call my function

that’ll print for me.

for me and then I’m going to print the suffix so the suffix is just that other

string we talked about just it trails with asterisks I’m then going to call

on a custom function called crlf all that’s going to do is just print a new

line I don’t know why I do that I could easily put that into the string but it’s

more fun to call functions although to be fair every time you call a function

you are jumping to an instruction elsewhere and so the CPU does pay a

trying to write programs for high performance you might not want to do that anyway so this is pretty

fast because i’m really just using an immediate and then i’m loading it into a register i’m not

actually touching global memory so this should be a lightning fast multiplication operation

let’s see if this actually works if i didn’t screw this up whoops what did i what did i do there oh no

i have too many videos now

gosh okay clear and make run oh what have I done undefined symbols CRLF did I

forget oh I forgot to copy paste my CRLF function yeah so again don’t worry

about CRLF all I’m doing is just printing a new line carriage return it’s

just you know this is from another example where I was trying to prove to

somebody you need to preserve registers and respect the ABI so don’t even worry

you know what I’m going to leave it as is because if I take that out then I have to take the time

to remove the push pop pair because there’s no point at that I’m doing that if I’m not

messing with those registers forget about that it’s not part of this video

anyway I’m going to run the program again and you can see that the result of multiplying

immediates is and so this whole string right here was my prefix so again not really the point of

the point of this video and then this is the result of multiplying those two different numbers

and then the suffix with the stars after so let me just prove this to you where’s the dang calculator

oh man i need to work on my icons like i just did something screwy and i have like no good icons

anymore on this virtual machine so we were going to multiply 233 by whoops by what was it 256.

five nine six four eight and you can see that’s on the screen five nine six four eight so we have

successfully multiplied signed integers and since they’re signed we could multiply negative numbers

if we wanted to i’m not going to here but you can now the next thing let’s try is let’s multiply

stuff sitting in global memory okay so i’m just going to copy this um where the heck is it

at the top we made two global integers we said integer a is equal to 233 and then 256

those were the same numbers that we just multiplied so we should probably get the same result

if we’re lucky so i’m saying i’m going to move both of 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 you that we can and then

instruction we did before the result is going to go into r14 so let’s see i’m gonna print the

prefix real fast here same kind of concept that we talked about before there’s just going to be

a prefix before the result and then i’m actually going to print the result with this line right

here or these lines i’m just going to print r14 which is holding the result at this point

and hey we can trust that R14 wasn’t killed by the system call because the

system call respects the ABI and then I’m gonna print my suffix right here and

then a CRLF and that’s basically the idea let’s just double check here that

we get the same result twice make run notice how it prints the same result

twice once with globals once with immediates so if you were wondering

before this video how to multiply immediates or how to multiply globals

well there you go just put them into registers first and then call I’m all

pretty fast let’s just do one other thing for fun I’m going to let’s see add

one number to our 14 so to the result of the multiplication and then I’m going to

add five to it just to prove to you that we can increase an integer by one and we

we print it before we do the prefix extra stuff just for fun so here I’m gonna increase r14 and

I’m gonna say that it is a q word I guess that’s implied already because r14 is considered a 64-bit

register but if we wanted to increase I don’t know just for the sake of argument if we wanted

to like increase this right here let me just show you real fast how we do it we would say increase

would say increase q word and then name the integer in global memory so in global memory

the system doesn’t really know by default if it’s a one byte integer a two byte integer or four or

eight so you just have to specify the data size so it knows which integers to look at when it’s

considering what the original value is and how to overflow and when to overflow but you know just

for fun I’m putting that in here so it’s going to increase the result by one and then it’s going to

and it’s going to do that using the addition instruction.

So we’re going to add R14 with 5.

We can put an immediate there,

and the result is going to be stored in R14.

So basically R14 is equal to R14 plus 5.

And so overall, when we add those two things in there,

the second result should now be about 6 higher than the first result.

So if you kind of look at this right here,

we have 648, and then we have 644,

which is 6 numbers higher than the original result.

than the original result. So these are the basics of integer arithmetic with

signed multiplication and addition. I think that’s all I really wanted to show

you. Yeah, okay. So I hope you learned a little bit of stuff from this video. I

hope you had a little bit of fun. Come back, I’ll see you in the next video and

happy coding! Hey everybody! Thanks for watching this video again from the

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

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

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 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

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.

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 coming for us all

Thank you.

Comments

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

Leave a Reply