Sign up ×

I am doing some exercises in assembly language and I found a question about optimization which I can't figure out. Can anyone help me with them

So the question is to optimize the following assembly code:


mov dx, 0 ---> this one I know-> xor dx,dx


cmp ax, 0
je label


mov ax, x
mov si, 16  
idiv si     

----> Most I can think of in this example is to subs last 2 lines by idiv 16, but I am not sure


mov ax, x
mov bx, 7
mul bx
mov t, ax


mov si, offset array1
mov di, offset array2
; for i = 0; i < n; ++i
   mov bx, [si]
   mov [di], bx
   add si, 2
   add di, 2
loop do
share|improve this question

2 Answers 2

up vote 5 down vote accepted

For example 2, you should look at the and or test opcodes. Similar to example 1, they allow you to remove the need for a constant.

For example 4, remember that x * 7 is the same as x * (8 - 1) or, expanding that, x * 8 - x. Multiplying by eight can be done with a shift instruction.

For example 5, you'd think Intel would have provided a much simpler way to transfer from SI to DI, since that is the whole reason for their existence. Maybe something like a REPetitive MOVe String Word :-)

share|improve this answer
Thank you. It is really helpful. – Alex Apr 6 '12 at 3:44

For example three, division by a power of two can be implemented as a right shift.

Note that in example 5, the current code fails to initialize CX as needed (and in the optimized version, you'd definitely want to do that too).

share|improve this answer
Common misconception. idiv works on signed integers and.. well -3/2 != -3 >> 1. – Voo Apr 6 '12 at 11:18
@Voo: You need to look a little more carefully at the x86 instruction set, particularly the fact that it has both shr (logical shift right) and sar (arithmetic shift right). sar produces arithmetically correct results for dividing either positive or negative numbers by powers of 2. – Jerry Coffin Apr 6 '12 at 13:23
No you're missing the point. It's not that the sign bit isn't extended. There are basically 3 different modes of division (truncating, modulus, floor). And the sign extending right shift trick only works for the modulus and floor definitions. Now the problem is that C and co all demand truncating division and well - it doesn't work there. Hence -3/2 == -1 while -3 >> 1 == -2. (can be fixed with 2 additional instructions though and is usually still far more efficient) – Voo Apr 6 '12 at 15:19
@Voo: Who said anything about producing the same result as C (or any other high level language)? – Jerry Coffin Apr 6 '12 at 15:25
Well the original code uses idiv, idiv does truncating division (not that surprising, although I'm not sure whether x86 or c was first) and the goal is to optimize the code which generally includes not changing the result? – Voo Apr 6 '12 at 15:31

Your Answer


