Hello ASM Community!

I always struggle with topic titles...

Im hoping you guys could help me out a little, im stuck with some snippets of code.

For the past 3 years i have been slowly teaching myself the ASM language, with no prior programming knowledge. Im not learning by writing applications, but rather researching and disassembling executables, mostly games. Now and then i come across something that i have to really look into a learn the in's and out's of, and the examples below have been cracking my skull for the past month.

I know these mnemonics, but never had to deal with them directly.

Here are three examples of the logics im researching, from the games code;

;this one moves down the {array} where each structure type is 0x28 in size. So {var_int}=0 is 0x0 is base, {var_int}=1 is 0x28, {var_int}=2 is 0x50 etc.

mov ebp, {var_int}

lea esi,

shl esi, 3

lea ebx, {array_ptr}

;this one moves down the {array} where each structure type is 0x68 in size. So {var_int}=0 is 0x0 is base, {var_int}=1 is 0x68, {var_int}=2 is 0xD0 etc.

mov edi, {var_int}

lea eax,

lea esi,

shl esi, 3

lea ebx, {array_ptr}

;this one moves down the {array} where each structure type is 0x70 in size. So {var_int}=0 is 0x0 is base, {var_int}=1 is 0x70, {var_int}=2 is 0xE0 etc.

mov edi, {var_int}

lea esi, ds:0

sub esi, edi

shl esi, 4

lea ebx, {array_ptr}

I dont quite understand how these are going from a input integer to large number, something is throwing me off...

I would appreciate any help regarding this.

Thanks!

-ConceptDroid

I always struggle with topic titles...

Im hoping you guys could help me out a little, im stuck with some snippets of code.

For the past 3 years i have been slowly teaching myself the ASM language, with no prior programming knowledge. Im not learning by writing applications, but rather researching and disassembling executables, mostly games. Now and then i come across something that i have to really look into a learn the in's and out's of, and the examples below have been cracking my skull for the past month.

I know these mnemonics, but never had to deal with them directly.

**SHL**and**SHR**i have trouble understanding, yet i know they shift at a binary level, and the others are, eg.**lea esi,**, i know**LEA**, but the calculation afterwords i am struggling with.Here are three examples of the logics im researching, from the games code;

;this one moves down the {array} where each structure type is 0x28 in size. So {var_int}=0 is 0x0 is base, {var_int}=1 is 0x28, {var_int}=2 is 0x50 etc.

mov ebp, {var_int}

lea esi,

shl esi, 3

lea ebx, {array_ptr}

;this one moves down the {array} where each structure type is 0x68 in size. So {var_int}=0 is 0x0 is base, {var_int}=1 is 0x68, {var_int}=2 is 0xD0 etc.

mov edi, {var_int}

lea eax,

lea esi,

shl esi, 3

lea ebx, {array_ptr}

;this one moves down the {array} where each structure type is 0x70 in size. So {var_int}=0 is 0x0 is base, {var_int}=1 is 0x70, {var_int}=2 is 0xE0 etc.

mov edi, {var_int}

lea esi, ds:0

sub esi, edi

shl esi, 4

lea ebx, {array_ptr}

I dont quite understand how these are going from a input integer to large number, something is throwing me off...

I would appreciate any help regarding this.

Thanks!

-ConceptDroid

Go through the code line by line and try heavily commenting it until you understand it

The code is just an obfuscation of ebx = array_ptr + var_int * 40.

It's done as an optimization because multiplication (MUL) in ASM is a costly operation. So if you can avoid a MUL by using a 1 or 2 faster instructions like LEA and SHL then your code will run faster.

Here's the more direct version of the code

;this one moves down the {array} where each structure type is 0x28 in size. So {var_int}=0 is 0x0 is base, {var_int}=1 is 0x28, {var_int}=2 is 0x50 etc.

mov ebp, {var_int}

;; ebp = var_int

lea esi,

;; esi = var_int + var_int * 4 = var_int * 5

shl esi, 3 ;; shift 3 bits left = multiply by 8

;; esi = 8 * (var_int * 5) = var_int * 40

lea ebx, {array_ptr}

;; ebx = array_ptr + var_int * 40

;; 40 decimal = 0x28 hex

The code is just an obfuscation of ebx = array_ptr + var_int * 40.

It's done as an optimization because multiplication (MUL) in ASM is a costly operation. So if you can avoid a MUL by using a 1 or 2 faster instructions like LEA and SHL then your code will run faster.

Here's the more direct version of the code

MOV eax, {var_int}

MOV ecx, 40

MUL ecx ;; eax = var_int * 40

LEA ebx, {array_ptr}

Go through the code line by line and try heavily commenting it until you understand it

;this one moves down the {array} where each structure type is 0x28 in size. So {var_int}=0 is 0x0 is base, {var_int}=1 is 0x28, {var_int}=2 is 0x50 etc.

mov ebp, {var_int}

;; ebp = var_int

lea esi,

;; esi = var_int + var_int * 4 = var_int * 5

shl esi, 3 ;; shift 3 bits left = multiply by 8

;; esi = 8 * (var_int * 5) = var_int * 40

lea ebx, {array_ptr}

;; ebx = array_ptr + var_int * 40

;; 40 decimal = 0x28 hex

The code is just an obfuscation of ebx = array_ptr + var_int * 40.

It's done as an optimization because multiplication (MUL) in ASM is a costly operation. So if you can avoid a MUL by using a 1 or 2 faster instructions like LEA and SHL then your code will run faster.

Here's the more direct version of the code

MOV eax, {var_int}

MOV ecx, 40

MUL ecx ;; eax = var_int * 40

LEA ebx, {array_ptr}

Thanks for replying!

It seems im having problems understanding the, eg. calculations, aswell as i dont see how SHL its multplying by 8.

Say, if EBP was 3, (I gather in this example you ignore the +0 here)

**LEA ESI,**= 3 + 3 * 4 = 15d, then

**SHL ESI, 3**= 15 * 8 = 78d??...

Say, if EBP was 3, (I gather in this example you ignore the +0 here) LEA ESI, = 3 + 3 * 4 = 15d, then SHL ESI, 3 = 15 * 8 = 78d??...

15 * 8 = 120 (*** not 78 ***)

SHL

Binary math uses powers of 2.

0001b = 1 = 0x01

If we shift left by 2 bits

0100b = 4 = 0x04

Because shift left by 2 bits is like multiplying by 4 (2^2 = 4)

LEA

Perhaps you should RTM (read the manual). The LEA opcode has 5 parameters

LEA A,

;; A = Any register

;; B = Any register or 0

;; C = Any register or 0

;; D = 2^0 or 2^1 or 2^2 or 2^3 (1 or 2 or 4 or 8)

;; E = A memory address 0 to 4.29~billion

**
**

EBP+EBP*4+0 = EBP*4 + EBP + 0 = 5 * EBP + 0 = 5 * EBP :)

Basically, this is how you multiply something by 5. It's usually faster than using mul.

1 = 00000001

2 = 00000010

3 = 00000011

4 = 00000100

5 = 00000101

6 = 00000110

7 = 00000111

8 = 00001000

Let's take 3: 00000011

Let's shoft it 1 place to the left. We get 00000110, which is 6.

It seems im having problems understanding the, eg. calculations, aswell as i dont see how SHL its multplying by 8.

Shifting left once is the same as multiplying times two, twice is times four, three times is times eight, etc.

In short, we are utilizing a known characteristic of the binary number system for efficiency. To calculate a shift's effect mathematically, use

I would recommend studying more on binary and powers-of-two.

EBP+EBP*4+0 = EBP*4 + EBP + 0 = 5 * EBP + 0 = 5 * EBP :)

Basically, this is how you multiply something by 5. It's usually faster than using mul.

calculations, aswell as i dont see how SHL its multplying by 8.

1 = 00000001

2 = 00000010

3 = 00000011

4 = 00000100

5 = 00000101

6 = 00000110

7 = 00000111

8 = 00001000

Let's take 3: 00000011

Let's shoft it 1 place to the left. We get 00000110, which is 6.

It seems im having problems understanding the, eg. calculations, aswell as i dont see how SHL its multplying by 8.

Shifting left once is the same as multiplying times two, twice is times four, three times is times eight, etc.

In short, we are utilizing a known characteristic of the binary number system for efficiency. To calculate a shift's effect mathematically, use

**2^x**where

**x**is the number of bits you want to shift; left for multiplication and right for division.

I would recommend studying more on binary and powers-of-two.

It's not just binary, any number system can multiply by shifting. A decimal number can be shifted to the left to multiply by 10. Twice to multiply by 100 and so on. In hex you can multiply by factors of 16 and in Oct you can multiply by factors of 8. It should come as no surprise you can multiply or divide by 2 when shifting binary numbers.

Spara

Spara