Hello, my name is Typhoon and this is the last lecture of our section, and many arithmetic instructions
are available, but we are going to show a selection of them.
And the others are similar to what you learned here.
So before we investigate arithmetic instructions and keep in mind that we use the printf with more than
two arguments, so we need an additional register.
The first one.
The first argument goes into RTI.
The second one into RSI and the third one into RDX.
So this is how Printf expects us to provide the arguments in Linux and you will learn more about that
later when we talk about the calling conventions, which you will learn that in next sections.
And here there is a instructions here.
The first instruction is Add, which can be used to add signed or unsigned integers.
The second operand source is added to the first operand destination and the result is placed in the
first operand destination here.
And the destination operand can be a register or a memory location.
So the source can be an immediate value, a register or a memory location.
The source and destination cannot be a memory location in the same instruction, and when the resulting
sum is too large to fit in the destination, the F flag is set for signed integers.
So for unsigned integer, the o f flag is then set.
So.
When the result is zero, the z f flag is set to one and when the result is negative, the F flag is
set.
And the subtraction with sub is similar to the Add instruction.
Uh, we can see it right here, adding and subtracting.
So here the.
To increment a register or a value in a memory location with one use the I and C.
Instructions.
Similarly, the a C can be used to decrement a register or value in a memory.
Location with one.
So the arithmetic shift instructions are a special breed.
So here you will see that at the end of the code here somewhere here.
So here if you shift left here.
So the shift left is Sal is in fact multiplying.
So if you shift left one position, you are multiplying by two.
Every bit is shifted.
One place to the left and zero is added to the right.
So take the binary number one shift left one place and you obtain binary 10 or 2 in decimal representation.
So you are getting from 0 to 2 and shift one shift left, one place again and you have a binary one
zero 0 or 4 in decimal representation.
So if you shift left two position, you multiply by four.
But what if you want to multiply by six?
So you shift left two times and then add two times the original source in that order.
So shift right as r.
S a r here.
Uh, is similar to a shift left, but it means dividing by two.
So every bit is shifted one place to the right and an additional bit is added to the left.
So.
Here.
There is a complication.
However, if the original value was negative, the leftmost bit would be one, and if the shift instruction
added two added a zero, the bit at the left, the value would become positive and the result would
be wrong.
So in the case of negative value as a R will add a one bit to the left and in the case of positive value,
zero bits will be added to the left and this is called sign extension.
So by the way, a quick way to see if a hexadecimal number is negative is to look at byte seven.
This is the leftmost byte continuing from byte zero, which is the rightmost byte.
So the number is negative.
If byte zero starts with an eight, nine, A, B, C, D, E, or F, but you need to take into account
all eight bytes.
For example, the byte zero x.
Uh, the device.
The 12 is still a positive number because the leftmost byte, which is not shown here, is zero.
And there's also no arithmetic shift instructions.
They will be discussed in next lecture.
And next here we multiply integers for multiplying the unsigned integers you can use mul here.
Um, now we will hear, uh, mul for unsigned multiplication.
So I think, uh, so the in the product shift.
Right.
Increment number.
Total integer quotient and product.
Yes.
And here but we use the I'm u l.
This is assigned multiple action which offers more flexibility so I can take one, 2 or 3 operands.
And in our example we use one operand, as you can see here.
And here.
And the as I said in our example, we use this one operand and the operand following the I mul instruction.
I mul instruction is multiplied with the value in rax right.
So you may expect that the resulting product is stored in Rax, but that is not entirely correct.
So let's illustrate an example here.
So you can verify that when you multiply, for example, a two digit number with a three digit number,
the product has 4 or 5 digits.
So when you multiply 4 to 8 bit digit with 30 bit digit, you will obtain 77, 77 bit digit or 78 bit
digit.
And that value does not fit in 64 bit register.
Right.
So to cope with this, the instruction I moved here Am will store the lower 64 bits of the resulting
product in Rax and upper 64 bits in RDX.
And this can be very deceptive.
Okay, so now let's experiment a little bit here.
So go back to the source code here, modify the number one so that it contains here.
Number one.
One, two.
Three, four.
One, 234567890.
And again.
One, two, three, four, five, six, seven.
That's it yeah seven and now and modify the number 2 to 100 and the product will just fit in racks so
you can check the here you would.
As you can see, we got an error, but missing node Unix like implies executable stack.
Yeah, this is just a warning and not an error here.
And as you can see here, we got very different result here.
And if it started the budget.
And in order to debug this, we need to we will put a break before the I mole instruction.
The started here.
And we will, uh, here we will put a break before the I instruction here, which is for the multiplying.
That's it.
Now.
Let's go.
And here we stopped it now.
Ugh.
Now.
The result of the multiplication here will be.
That's actually and that's the result of the multiple action here will be this number.
And as you can see in racks after the instruction is executed.
Right.
Uh, the new modified.
Now, uh, actually, let's actually modify number two into 10,000.
Obsession.
Let's stop the debugging.
It still have that breakpoint here?
One, two, three.
Now it's in 10,000.
The bugging is started.
Let's go to email here.
And with this, um, after, uh, of course, after setting the restart, after setting the 10,000 in
number to stop the debugging and then start it again.
And after look after the racks after executing moved here like this.
And here.
Um.
So you can see that the product is a large negative value here, right?
So this is because the most significant bit in Rax is a one.
And CSM concludes that this must be a negative number.
Also, Printf thinks that Rax contains a negative number because Rax contains a one bit in the leftmost
position, so it's assumed to be negative.
So be careful with printf.