Search code examples
assemblyx86fixed-point

How would the MUL operation on AX with Pi (3,1415..) in (8.8) format work in Assembly?


Im new to Assembly and am learning Fix-point arithmetic.

AX is a 16-Bit register-

 MUL Pi  ; Multiplies EAX with Pi and stores result in EAX
 DIV 256 ; Divides EAX by 256 which equals the necessary right- shift for the 8,8 format

But I dont think it works like this.


Solution

  • A MUL instruction with a word sized operand multiplies AX with that operand and places its result in DX:AX. If both operands are in 8.8 format, the result will be in 16.16 format with the integral part in DX and the fractional part in AX. To convert this to 8.8 format, you take the contents of DL and AH like this:

    MUL Pi        ; multiple by Pi, leaving the integral part in DX and the fraction in AX
    MOV AL, AH    ; move the fractional part into place
    MOV AH, DL    ; move the integral part into place
    

    And everything should work out just fine. Note that the rounding might be off a little. You can correct for that like this:

    MUL Pi        ; multiple by Pi, leaving the integral part in DX and the fraction in AX
    ADD AX, 0080h ; apply rounding to AH
    ADC DX, 0     ; apply carry if any
    MOV AL, AH    ; move the fractional part into place
    MOV AH, DL    ; move the integral part into place
    

    This rounds the result correctly according to the principle

    round(x) = ⌊x + 0.5⌋