; Multiplication et division en virgule fixe, spécifique au 386. ; ; Appelable en C near comme suit: Fixedpoint FixedMul(Fixedpoint M1, Fixedpoint M2) ; ; Fixedpoint FixedDiv(Fixedpoint Dividend, Fixedpoint Divisor); ; ; Testé avec TASM 4.0 par Jim Mischel 12/16/94. ; .model small .386 .code public _FixedMul,_FixedDiv ; Multiplie les deux valeurs en virgule fixe. FMparms struc dw 2 dup(?) ;adresse de retour & BP empilé M1 dd ? M2 dd ? FMparms ends align 2 _FixedMul proc near push bp mov bp,sp mov eax,[bp+M1] imul dword ptr [bp+M2] ;multiplie add eax,8000h ;arrondit en ajoutant 2^(-16) adc edx,0 ;la partie entière du résultat est dans DX shr eax,16 ;met la partie fractionnelle dans AX pop bp ret _FixedMul endp ; Divise une valeur en virgule fixe par une autre. FDparms struc dw 2 dup(?) ;adresse de retour & BP empilé Dividend dd ? Divisor dd ? FDparms ends align 2 _FixedDiv proc near push bp mov bp,sp sub cx,cx ;suppose le résultat positif mov eax,[bp+Dividend] and eax,eax ;dividende positif? jns FDP1 ;oui inc cx ;note que le dividende est négatif neg eax ;rend le dividende positif FDP1: sub edx,edx ;en fait un dividende sur 64 bits, puis décale ;décale de 16 bits sur la gauche afin que le résultat ; ;soit dans EAX rol eax,16 ;met a partie fractionnelle du dividende ;dans le mot high de EAX mov dx,ax ;met la partie entière du dividende dans DX sub ax,ax ;vide le mot low de EAX mov ebx,dword ptr [bp+Divisor] and ebx,ebx ; diviseur positif? jns FDP2 ;oui dec cx ;note que c'est un diviseur négatif neg ebx ;rend le diviseur positif FDP2: div ebx ;divise shr ebx,1 ;diviseur/2, moins 1 si le diviseur est adc ebx,0 ; pair dec ebx cmp ebx,edx ;paramètre Carry si le reste est au moins adc eax,0 ;égale à la moitié du diviseur, puis ;l'utilise pour arrondir si nécessaire and cx,cx ;le résultat devrait-il être négatif? jz FDP3 ;non neg eax ;oui, il devient négatif FDP3: mov edx,eax ;retourne le résultat dans DX:AX, ;la partie fractionnelle est déjà dans AX shr edx,16 ;la partie entière du résultat dans DX pop bp ret _FixedDiv endp end