Reputation: 458
Assume that you are given values in eax,ecx. Write a piece of code that calculates 5*eax + 3*ecx + 1, and stores the result inside eax. (* means multiplication here).
My code :
;Initialize the values in eax and ecx
mov eax,3
mov ecx,4
;Compute 3*ecx
mov ebx,eax
mov eax,ecx
mov edx,3
mul edx
; Compute 5*eax
mov ecx,eax
mov eax,ebx
mov edx,5
mul edx
; Compute 5*eax + 3*ecx + 1
lea eax,[ecx + eax]
inc eax
Upvotes: 1
Views: 181
Reputation: 14057
Michael's (most excellent) solution can yet be slightly optimized for size (1 byte shorter), but this requires a little algebraic manipulation first.
5*eax + 3*ecx + 1
= 2*eax + 3*eax + 3*ecx + 1
= 2*eax + 3*(eax + ecx) + 1
This can be solved via ...
(Excluding initialization of EAX and ECX)
add ecx, eax ; 2 bytes
lea ecx,[ecx*2 + ecx] ; 3 bytes
lea eax,[eax*2 + ecx + 1] ; 4 bytes
Upvotes: 5
Reputation: 58427
If by "optimize" you mean optimize for instruction count, then sure, use lea
even more:
;Initialize the values in eax and ecx
mov eax,3
mov ecx,4
;Compute 3*ecx
lea ecx,[ecx*2 + ecx]
; Compute 5*eax
lea eax,[eax*4 + eax]
; Compute 5*eax + 3*ecx + 1
lea eax,[ecx + eax + 1]
This is also 16 bytes less in machine code size if my eyes serve me right.
The rules governing what you can compute with lea
are listed in the section Specifying an offset in Intel's manuals.
Upvotes: 6