views:

75

answers:

3

In principle, squaring the value of a register isn't hard:

mov ax, [var]
mov cx, [var]
mul cx         // square of answer is in DX:AX

But I got to thinking -- the course that I'm learning Assembly for prizes efficiency very highly; a difference of even a single line less could be worth up to 5 points.

I realize this is micro-optimization, but would the following code perform the the same way?:

mov ax, [var]
mul ax          // is answer still in DX:AX ?

I suppose a much simpler way of expressing my question: is AX (or AL/AH) a valid parameter for the mul and imul commands in 8086 assembly?

+2  A: 

Yes, mul ax puts ax*ax to dx:ax.

pts
+1  A: 

I would benchmark before assuming that it is faster as well. I can imagine that in hardware the ax = ax*ax operation will be more cumbersome than the mul bx equivalent. (I must admit this is pure speculation)

mvds
I wasn't predicting it was faster because it was multiplying by the AX register, but rather that it would be faster because it had one less execution (only one MOV command). The machine code between mul BX and mul AX only varies by the 3 bit register designation. Mine was just a question born of overcaution and self-doubt.
Raven Dreamer
@Raven Dreamer: In assembly language, fewer lines does not always mean faster. Always benchmark if your code is performance-critical.
Greg Hewgill
Exactly; the naive assumption that 1 instruction takes 1 clock tick (yes, been there) is incorrect.
mvds
@ Greg, Mvds: but as I stated in the question, I am specifically striving for fewer *lines*, not fastest runtime. Were this not for a course where number of *lines* was a grading metric, I'd agree with you. Perhaps "faster" was a poor choice of words.
Raven Dreamer
A: 

You can use mul ax it would do DX:AX = AX * AX but note that in this case you will lose the value you had in AX so if you need to use this value again sometime it is better to use the mul bx option, because BX remains intact.

Also if you use mul al or (mul ah) you will not do AX=AX*AX but AX=AL*AL (or AX=AL*AH) so if the value in AX is bigger than 255 you aren't doing a multiplication of AX because you completely ignore and overwrite the higher part of the value (you ignore AH).

Bob