NASM Forum > Programming with NASM

How are you multiplying by 3

<< < (2/3) > >>

fredericopissarra:

--- Quote from: gygzkunw on February 22, 2021, 02:11:02 PM ---edx+2 * edx = 3edx-> This is my question, how is this possible?
--- End quote ---

EDX + 2*EDX = EDX * (1 + 2) = EDX * 3

Elementary arithmetic.


--- Quote ---But earlier mov edx,ecx -> 0 was moved into edx

edx(0)+ 2*edx(0) =should equal to 0, right?
Do you understand what I am saying here?

--- End quote ---
Yep... this code is obviously WRONG. Or, at least, is incomplete (and ECX is updated in a loop).

gygzkunw:

--- Quote from: fredericopissarra on February 22, 2021, 03:40:15 PM ---
--- Quote from: gygzkunw on February 22, 2021, 02:11:02 PM ---edx+2 * edx = 3edx-> This is my question, how is this possible?
--- End quote ---

EDX + 2*EDX = EDX * (1 + 2) = EDX * 3

Elementary arithmetic.


--- Quote ---But earlier mov edx,ecx -> 0 was moved into edx

edx(0)+ 2*edx(0) =should equal to 0, right?
Do you understand what I am saying here?

--- End quote ---
Yep... this code is obviously WRONG. Or, at least, is incomplete (and ECX is updated in a loop).

--- End quote ---
I didn't say it wasn't elementary. To get 3 you have to add 1. The question is where does the 1 come from? Up till this point in the author does not explain it.

debs3759:
I can't figure out what you are not seeing? (EDX * 2) + EDX is obviously 3 * EDX, where are you seeing the "1" that you don't understand?

0 can be multiplied by any number...

mik3ca:

--- Quote from: gygzkunw on February 22, 2021, 12:21:15 AM ---
--- Code: ---...
; Here we calculate the offset into the line string, which is ecx X 3
mov edx,ecx ; ----> copy ecx which is 0 into edx
lea edx,[edx*2+edx]     ; ----> This is where i am stuck. How are you able to multiply by 3 over here?
LEA = [BASE +( INDEX * SCALE) + DISP)]
      if edx is 0, how are we able to multiply by 3
--- End code ---

--- End quote ---

I think LEA means load effective address. But instead of using that, I just use direct memory addressing.

Simplest way to multiply by 3 is this


--- Quote ---mov EAX,3
mul ECX

--- End quote ---

It will give you the result as EDX:EAX but if the value is less than roughly 4 million (whatever 2 to the exponent of 32 is) then you can ignore EAX.

But what I would recommend is to use any register ending in BX or BP because then you can directly address the offset of a string.

The way I directly address a string using a multiply by 3 idea (assuming the addressing model is a modern model) is as follows and here we assume the string is small (what normal string would be 4 million bytes anyway?):


--- Code: ---baseoffset equ 666h ;location of the entire string (I just picked 666h as an example)

mov EAX,3           ;multiplier value
mul EBX               ;EAX times EBX = EDX:EAX
mov EBX,EAX     ;set EBX as result

--- End code ---

Now if you use the above code, and add this code, you can set a byte to the string:

--- Code: ---mov DL,77h ;77h is a random byte value I chose
mov [baseoffset+EBX],DL ;inject it directly into the string location

--- End code ---

Or replace the above two lines with the line below if you want to read a byte:

--- Code: ---mov DL,[baseoffset+EBX]

--- End code ---

debs3759:

--- Quote from: mik3ca on February 27, 2021, 01:56:47 AM ---
--- Quote from: gygzkunw on February 22, 2021, 12:21:15 AM ---
--- Code: ---...
; Here we calculate the offset into the line string, which is ecx X 3
mov edx,ecx ; ----> copy ecx which is 0 into edx
lea edx,[edx*2+edx]     ; ----> This is where i am stuck. How are you able to multiply by 3 over here?
LEA = [BASE +( INDEX * SCALE) + DISP)]
      if edx is 0, how are we able to multiply by 3
--- End code ---

--- End quote ---

I think LEA means load effective address. But instead of using that, I just use direct memory addressing.

Simplest way to multiply by 3 is this


--- Quote ---mov EAX,3
mul ECX

--- End quote ---

It will give you the result as EDX:EAX but if the value is less than roughly 4 million (whatever 2 to the exponent of 32 is) then you can ignore EAX.
--- End quote ---

Doing that, you are destroying the contents of other registers than the one you want to multiply, and you are creating longer and slower code.


--- Quote ---But what I would recommend is to use any register ending in BX or BP because then you can directly address the offset of a string.
--- End quote ---

In 16-bit code, you can use BX or BP as the base, and SI or DI as the index. In 32-bit code you can use any 32-bit register for either, which is why LEA is so useful.


--- Quote ---The way I directly address a string using a multiply by 3 idea (assuming the addressing model is a modern model) is as follows and here we assume the string is small (what normal string would be 4 million bytes anyway?):


--- Code: ---baseoffset equ 666h ;location of the entire string (I just picked 666h as an example)

mov EAX,3           ;multiplier value
mul EBX               ;EAX times EBX = EDX:EAX
mov EBX,EAX     ;set EBX as result

--- End code ---

--- End quote ---

Again, you are making it more complicated than it needs to be, and your code is bloated, slow and destructive.


--- Code: ---lea EBX,[EBX*2 + EBX]
--- End code ---

uses one line of code, one instruction, and produces smaller, faster code without destroying EAX or EDX.


--- Quote ---Now if you use the above code, and add this code, you can set a byte to the string:

--- Code: ---mov DL,77h ;77h is a random byte value I chose
mov [baseoffset+EBX],DL ;inject it directly into the string location

--- End code ---

Or replace the above two lines with the line below if you want to read a byte:

--- Code: ---mov DL,[baseoffset+EBX]

--- End code ---

--- End quote ---

Not sure how this is relevant, the OP is trying to understand hoe to use LEA to do simple math.

Navigation

[0] Message Index

[#] Next page

[*] Previous page

Go to full version