Morgan - Numerical Methods (523161), страница 42
Текст из файла (страница 42)
DX contains the integer portion, AX the;fractional portion..dataroundupdb3fH, 0fH, 1H, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.codenewtproc uses si di,dividend:word, divisor:wordlocalshifted_bits:byte,submovmovax,axbyte ptr shifted_bits, albyte ptr pass_count, 4movmovnormalize:orjsshlinccmpjgjmp316pass_count:bytecx, axax, word ptr divisorax, axtop_endax, 1clcl, 0fhdivide_by_zeroshort normalize;the divisor must be;zeroFXMATH.ASMtop_end:movmovmovtestjnztestjzjmpbyte ptr shifted_bits, cles, ax;store normalized;divisorax, word ptr divisorax, 0f8hshift_rightal, 7hdivide_by_zeroshort shift_leftshift_right:shrtestjejmpword ptr ax, 1ax, 0f8hdivisor-justifiedshort shift_rightshift-left:testjneshljejmpax, 4hdivisor_justifiedword ptr ax, 1divisor_justifiedshort shift_leftdivisor_justified:movsubmovmovdivsubmovdivmovsubdivmovmovmovsi,bx,cx,ax,clah,cl,clch,al,clah,cx,bx,offset roundupbxax32;vah4alalchesax;save zpass:mulmovaxal, ah;z squared;adjust for 16-bit;fixed point317NUMERICAL METHODSmovah, dlmulmovcxax, dx;vkz2;adjust againshlbx, 1;2*zsubaddadcbx, axbl, byte ptr [si]bh, 0;2z - vkz2;add rounding bitsmovincdecjnzax, bxsibyte ptr pass_countpass;save zprepare_shift:movmulsubmovsubjnsax, word ptr dividendbxcx, cxcl, byte ptr shifted_bitscl, 8adjust_leftclnegadjust_right:shrrcrloopjmpdx, 1ax, 1adjust_rightshort exitadjust_left:shlrclloopax, 1dx, 1adjust_leftexit:retoops:divide_by_zero:318FXMATH.ASMsubnotjmpnewt endpax, axaxshort exit;error of some sort; ******circle proc uses bx cx dx si di, x-coordinate:dword, y-coordinate:dword,increment:wordlocalx:dword, y:dword, x_point:word, y_point:word, countmovmovmovmovmovmovmovmovax, worddx, wordword ptrword ptrax, worddx, wordword ptrword ptrsubmovmovax, axx_point, axy_point, axmovmovmovax, 4876hdx, 6hcx, word ptr incrementptr x-coordinateptr x_coordinate[2]x, axx[2], dxptr y-coordinateptr y-coordinate[2]y, axy[2], dxget_num_points:shlrclloopmovax, 1dx, 1get_num_pointscount, dxset_point:movmovaddjncax, word ptr xdx, word ptr x[2]ax, 8000hstore_x;load local variables;x coordinate;y coordinate;2*pi;make this a negative;power of two;2*pi radians;divide by l0000h;add .5 to round up;to integers319NUMERICAL METHODSadcstore_x:movmovmovaddjncadcstore_y:movdx, 0hx_point, dxax, word ptr ydx, word ptr y[2]ax, 8000hstore_ydx, 0h;add.5y_point, dx;your routine for writing;to the screen goes here;and uses x_point and;y_point as screen coordi;natesmovmovmovupdate_x:sarrcrdx, 1ax, 1loopupdate_xsubword ptr x, axsbbword ptr x [2], dxmovmovmovupdate_y:sarrcrloopaddadcdecjnz320ax, word ptr ydx, word ptr y [2]cx, word ptr increment;please note the arithmetic;shifts;to preserve the correct;quadrant;new x equals x - y *;incrementax, word ptr xdx, word ptr x [2]cx, word ptr incrementdx, 1ax, 1update_yword ptr y, axword ptry [2], dxcountset_point;new y equals y + x *;incrementFXMATH.ASMretcircle endp; ******lineprocuses bx cx dx si di, xstart:word, ystart:word, xend:word,yend:wordlocalx:word, y:word, decision:word, x_dif:word, y_dif:word,xstep_diag:word,ystep_diag:word, xstep:word, ystep:word, diag_incr:word,incr:wordmovmovmovmovax, word ptr xstartword ptr x, axax, word ptr ystartword ptry, axdirection:movsubjnsax, word ptr xendax, word ptr xstartlarge_xnegmovjmplarge_x:movstore_xdif:movaxword ptr xstep_diag, -1short store_xdifmovsubjnsnegmovax, word ptr yendax, word ptr ystartlarge_yaxword ptr ystep_diag, -1;initialize local variables;total x distance;which direction are we;drawing?;went negativeword ptr xstep_diag, 1x_dif, ax;y distance;which direction?321NUMERICAL METHODSjmplarge_y:movstore_ydif:movsignsshort store_ydifword ptr ystep_diag, 1word ptr y_dif, ax;direction is determinedbymovax, word ptr x_difmovcmpjgbx, word ptr y_difax, bxbigger_x;the axis with greater;difference;becomes our referencemovy_dif, axmovx_dif, bxoctant:submovmovmovjmpbigger_x:movax, axword ptr xstep, axax, word ptr ystep_diagword ptr ystep, axsetup_incax, word ptr xstep_diagmovsubmovword ptr xstep, axax, axword ptr ystep, axsetup_inc:movax, word ptr y_dif322shlmovsubmovsubmovax, 1word ptrax, wordword ptrax, wordword ptrmovax, word ptr decisionmovmovbx, word ptr xcx, word ptr x_dif;we have a bigger y move;than x;x won't change on;nondiagonal steps,;y changes every step;x changes every step, y;changes only;on diagonal steps;calculate decision;variableincr, axptr x_difdecision, axptr x-difdiag_incr, ax;we will do it all in the;registersFXMATH.ASMmovdx, word ptr yline_loop:;Put your routine for turning pixels on here.
Be sure to push ax, cx, dx, and bx;before destroying them, they are used here. The value for the x coordinate is in;bx and the value for they coordinate is in dx.orjnsax, axdpositiveaddbx, word ptr xstepaddaddjmpdpositive:addaddadddx, word ptr ystepax, incrshort chk_loopchk_loop:loopretline endp;;calculate new position and;update the decision;variablebx, word ptr xstep_diagdx, word ptr ystep_diagax, word ptr diag_incrline_loop;; ******;smul64- signed mul64smul64 proc uses bx cx dx di si, operand0:qword, operand1:qword, result:wordlocalsign:bytesubmovax, axbyte ptr sign, almovorjnsnotax, word ptr operand0[6]ax, axchk_secondbyte ptr sign323NUMERICAL METHODSnotnotnotnegjcaddadcadcword ptr operand0[6]word ptr operand0[4]word ptr operand0[2]word ptr operand0[0]chk_secondword ptr operand0[2], 1word ptr operand0[4], 0word ptr operand0[6], 0chk_second:movorjnsnotnotnotnotnegjcaddadcadcax, word ptr operand1[6]ax, axmultiply_alreadybyte ptr signword ptr operand1[6]word ptr operand1[4]word ptr operand1[2]word ptr operand1[0]chk_secondword ptr operand1[2]word ptr operand1[4],0word ptr operand1[6],0multiply_alreadyinvokemu164, operand0, operand1, resulttestjemovnotnotnotnotnotnotnotnegjcaddadcadcadc324byte ptr sign, -1leave-alreadydi, word ptr resultword ptr [di][14]word ptr [di][12]word ptr [di][10]word ptr [di][8]word ptr [di][6]word ptr [di][4]word ptr [di][2]word ptr [di][0]leave_alreadyword ptr [di][2], 1word ptr [di][4], 0word ptr [di][6], 0word ptr [di][8], 0FXMATH.ASMadcadcadcword ptr [di][10], 0word ptr [di][12], 0word ptr [di][14], 0leave_already:retsmul64 endp;; ******;divmul- division by iterative multiplication;Underflow and overflow are determined by shifting.
if the dividend shifts;out on any attempt to normalize then we have 'flowed' in which ever;direction it shifted out.divmul procuses bx cx dx di si, dividend:qword, divisor:qword, quotient:wordlocaltemp[8]:word, dvdnd:qword, dvsr:qword, delta:qword,divmsb:byte,lp:byte,tmp:qwordcld;upwardsubmovcx, cxbyte ptr lp, 6leamovmovorormovmovmovmovmOVmovororjedi, wordax, worddx, wordcx, axcx, dxword ptrword ptrax, worddx, wordword ptrword ptrcx, axcx, dxovrflwsubleacx, cxdi, word ptr dvsr;should only take six;passesptr dvdndptr dividend[0]ptr dividend[2][di][0], ax[di][2], dxptr dividend[4]ptr dividend[6][di][4], ax[di][6], dx;zero dividend325NUMERICAL METHODSmovmovorormovmovmovmovmovmovororjesubmovfind_msb:decdeccmpjemovsubcmpjbjatestjneax, worddx, wordcx, axcx, dxword ptrword ptrax, worddx, wordword ptrword ptrcx, axcx, dxovrflwptr divisor[0]ptr divisor[2][di][0], ax[di][2], dxptr divisor[4]ptr divisor[6][di][4], ax[di][6], dxax, axbx, 8;look for MSB of divisorbxbxword ptr [di][bx], axfind_msbax, word ptr [di][bx]cx, cxbx, 2hshift_leftshift_rightword ptr.
[di][bx], 8000hnorm_dvsrshift_left:decshltestjnejmpcxax, 1ah, 80hnorm_dvsrshift-leftshift_right :incshrorjejmpcxax, 1ax, axnorm_dvsrshift-right326;zero divisor;di is pointing at dvsr;get MSW;save shifts here;see if already normalized;normalized?;its already there;count the number of shifts;to normalize;count the number of shiftsFXMATH.ASM;to normalizenorm_dvsr:testjneshlrclrclrcljmpword ptr [di][6],norm_dvdndword ptr [di][0],word ptr [di][2],word ptr [di][4],word ptr [di][6],norm_dvsr8000h1111;we want to keep;the divisor;truly normalized;for maximum;precision;this should normalize dvsrnorm_dvdnd:cmpbl, 4hjbeaddjmpchk_2cl, 10hready_dvdndcmpjaesubof shiftbl, 2hready_dvdndcl, 10h;bx still contains pointer;to dvsr;adjust for wordchk_2:ready_dvdnd:leaorjeorjnsnegsubjmpdi, word ptr dvdndcl, clmakedeltacl, cldo_dvdnd_rightclch, chdo_dvdnd_leftdo_dvdnd_right:shrrcrword ptr [di][6], 1word ptr [di][4], 1rcrrcrloopsubororword ptr [di][2], 1word ptr [di][0], 1do_dvdnd_rightax, axax, word ptr [di][6]ax, word ptr [di][4];adjusting again for size;no adjustment necessary;no error on underflow;unless it becomes zero,;there may still be some;usable infonnation;this should normalize dvsr327NUMERICAL METHODSrepororjnemovmovstoswjmpdo_dvdnd_leftshlrclrclrcljcax, word ptr [di][2]ax, word ptr [di][0]setupdi, word ptr quotientcx, 4divmul_exitword ptrword ptrword ptrword ptrovrflw[di][0],[di][2],[di][4],[di][6],;if it is now a zero, that;is the result1111loopdo_dvdnd_leftmovmovmovmovswsi, didi, word ptr quotientcx, 4;significant bits shifted;out, data unusable;this should normalize dvsrsetup:rep;put shifted dividend into;quotientmakedelta:repmloop:328;this could be done with;a tablelealeamovmovswsi, word ptr dvsrdi, word ptr deltacx, 4notnotnotnegwordwordwordwordjcaddadcadcmloopword ptr delta[2], 1word ptr delta[4], 0word ptr delta[6], 0;move normalized dvsr;into deltaptrptrptrptrdelta[6]delta[4]delta[2]delta;attempt to develop with;2's compFXMATH.ASMreprepinvokemul64, delta, dvsr, addr templealeamovmovswsi, word ptr temp[8]di, word ptr tmpcx, 4invokeadd64, tmp, dvsr, addr dvsrleamovmovmovswinvokedi, word ptr divisorsi, word ptr quotientcx, 4mul64, delta, divisor, addr tempsubcmpax, axword ptr temp[6], 8000hjbaddadcadcadcno_round:repno_roundword ptrword ptrword ptrword ptr;an attempt to round;;please bear with me;.5 or above rounds uptemp[8], 1temp[10], axtemp[12], axtemp[14], axlealeamovmovswinvokesi, word ptr temp[8]di, word ptr tmpcx, 4decjejmpbyte ptr lpdivmul_exitmakedeltasubnotmovmovstoswjmpax, axaxcx, 4di, word ptr quotient;double dutyadd64, divisor, tmp, quotient;six passes for 64 bitsovrflw:rep;make infinite answerdivmul_exitdivmul_exit:329NUMERICAL METHODSpopfretdivmul endp; ******;divnewt- division by raphson-newton zero's approximationdivnewtquotient:wordlocalproc uses bx cx dx di si, dividend:qword, divisor:qword,temp[8]:word, proportion:qword, shift:byte, qtnt_adjust:byte,lp:byte, tmp:qword, unity:qwordcldsubmovcx, cxbyte ptr lp, 3movororororjeqtnt_adjust, clcx, word ptr dividend[0]cx, word ptr dividend[2]cx, word ptr dividend[4]cx, word ptr dividend[6]ovrflw;zero dividendsubororororjecx, cxcx, wordcx, wordcx, wordcx, wordovrflw;zero divisorsubmovfind_msb:leadecdeccmpje330;upward;should only take three;passesptr divisor[0]ptr divisor [2]ptr divisor[4]ptr divisor[6]ax, axbx, 8;look for MSB of divisordi, word ptr divisorbxbxword ptr [di][bx], axfind_msb;di is pointing at divisorFXMATH.ASMmovmovsubcmpjbjatestjnebyte ptr qtnt_adjust, blax, word ptr [di][bx]cx, cxbx, 2hshift_leftshift_rightword ptr [di][bx], 8000hnorm_dvsrshift_left:decshltestjnejmpcxax, 1ah, 80hsave_shiftshift_leftshift_right:incshrorjejmpcxax, 1ax, axsave_shiftshift_rightsave_shift:movsubshift_back:cmpjeshrrcrrcrrcrjmpnorm_dvsr:testjneshlrcl;get MSW;save shifts here;see if already normalized;normalized?;it's already there;count the number of shifts;to normalize;count the number of shifts;to normalizebyte ptr shift, clax, axword ptr [di][6], axnorm_dvsrword ptr [di][6],word ptr [di][4],word ptr [di][2],word ptr [di][0],shift_back;we will put radix point at;word three1111word ptr [di][4], 8000hmake_firstword ptr [di][0], 1word ptr [di][2], 1;the divisor;truly normalized331NUMERICAL METHODSrcljmpmake_first:movsubmovdivsubmovcorrect_dvsr:shlword ptr [di][4], 1norm_dvsr;for maximum;this should normalize;divisordx, 1000hax, axbx, word ptr [di][4];first approximation;;could come from a tablebxdx, dx;keep only the four;least bitscx, 4ax, 1;don't want to waste time;with a big shift when a;little one will sufficerclloopmovmovsubmovmovshrdx, 1correct_dvsrword ptr divisor[4],word ptr divisor[6],cx, cxword ptr divisor[2],word ptr divisor[0],dx, 1rcrmulax, 1bxshlax, 1rclmovsubmovmovmovdx, 1word ptrcx, cxword ptrword ptrword ptraxdxcxcx;reconstruct for first;attempt;don't want to waste time;with a big shift when a;little one will sufficeunity[4], dxunity[6], cxunity[2], cxunity, cxmakeproportion:movsub332;don't want to waste time;with a big shift when a;little one will suffice;this could be done with;a tableword ptr proportion[4], dxax, axFXMATH.ASMmovmovmovinvert_proportion:notnotnotnegword ptr proportion[6], axword ptr proportion[2], axword ptr proportion, axwordwordwordwordptrptrptrptrproportion[6]proportion[4]proportion[2]proportion;attempt to develop with;two's complementjcaddadcadcmloopword ptr proportion[2], 1word ptr proportion[4], 0word ptr proportion[6], 0andinvokeword ptr proportion[6], 1mul64, proportion, divisor, addr templealeamovmovswsi, word ptr temp[6]di, word ptr divisorcx, 4invokemul64, proportion, unity, addr templealeamOVmovswlealeamovmovswsi, word ptr temp[6]di, word ptr unitycx, 4decjejmpbyte ptr lpdiv_newt_shiftinvert_proportionsubnotmovax, axaxcx, 4mloop:si, word ptr temp[6]di, word ptr proportioncx, 4;six passes for 64 bitsovrflw:333NUMERICAL METHODSrepmovstoswjmpdivnewt_shift:leamovorjsqtnt_right:movsubmovsubjmpqtnt_left:negsubadddi, word ptr quotient;make infinite answerdivnewt_exitdi, word ptr divisorcl, byte ptr shiftcl, clqtnt_left;get shift count;positive, shift leftch, 10hch, clcl, chch, chqtlftclch, chcl, 10h;we want to take it to;the msbqtlft:shlrclrclrclloopdivnewt_mult:times dividendsubmovleastoswrep334word ptrword ptrword ptrword ptrqtlft[di][0],[di][2],[di][4],[di][6],1111;multiply reciprocalax, axcx, 8di, word ptr tempinvokemovmul64, dividend, divisor, addrtempbx, 4addmOVleaaddbl,di,si,si,byte ptr qtnt_adjustword ptr quotientword ptr tempbx;see that temp is clear;adjust for magnitude of;resultFXMATH.ASMcmprepjaemovmovswjmpwrite_zero:movmovswrepsubstoswdivnewt_exit:popfretdivnewtbl, 0ahwrite_zerocx, 4divnewt_exitcx, 3ax, axendpend335336Previous HomeAPPENDIX DFPMATH.ASM.DOSSEG.MODEL small, c, os_dosinclude math.inc;.data;.code;; ******;does a single-precision fabs;fp_intrnd proclocalusessi di, fp0:dword, fpl:wordflp0:qword,result:qwordreppushfcldxorleamovstoswsi,word ptr fp0di,word ptr flp0[2]cx,2replealeamovmovswinvokeintrnd, flp0, addr resultmovax, word ptr result[2]ax,axdi,word ptr flp0cx,4337NextNUMERICAL METHODSmovmovmovmovdx, worddi, wordword ptrword ptrptr result[4]ptr fpl[di], ax[di][2], dxpopfretfp_intrnd endp; ******;intrnd is useful for the transcendental functions; it rounds to the nearest integer according to the following logic:; intrnd(x) = if((x-floor(x)) <.5) floor(x);else ceil(x);;intrndproc uses bx dx di si, fp:qword, rptr:wordlocalreprepreppushfcldsubmovleastoswmovleastoswmovmovstoswax, axcx, 4di, word ptr temp0cx, 4di, word ptr temp1di, word ptr rptrcx, 4invokeinvokeandinvokeflr, fp, addr temp0flsub, fp, temp0, addr temp1word ptr temp1[4], 7fffh;cheap fabsflcomp,temp1, one_halfcmpjneax, 1intrnd_exitdo_ceil:invoke338temp0:qword, templ:qword, sign:byteflceil, fp, addr temp0FPMATH.ASMintrnd_exit:movmovmovmovmovpopfretintrndendpax, worddx, worddi, wordword ptrword ptrptr temp0[2]ptr temp0[4]ptr rptr[di][2], ax[di][4], dx;implements floor function;by calling flr;fp_floor procuses si di, fp0:dword, fpl:wordlocalflp0:qword,result:qwordreppushfcldxorleamovstoswsi,word ptr fp0di,word ptr flp0[2]cx,2replealeamovmovswinvokeflr, flP0, addr resultmovmovmovmovmovax, worddx, worddi, wordword ptrword ptrax,axdi,word ptr flp0cx,4ptr result[2]ptr result[4]ptr fpl[di], ax[di][2], dxpopfret339NUMERICAL METHODSfp_floor endp; ******;implements ceil function;by calling flceil;fp_ceil procuses si di, fp0:dword, fp1:wordlocalflp0:qword,result:qwordreppushfcldxorleamovstoswsi,word ptr fp0di,word ptr flp0[2]cx,2replealeamovmovswinvokeflceil, flp0, addr resultmovmovmovmovmovax, worddx, worddi, wordword ptrword ptrax,axdi,word ptr flp0cx,4ptr result[2]ptr result[4]ptr fp1[di], ax[di][2], dxpopfretfp_ceil endp;; ******;floor greatest integer less than or equal to x;single precisionflr340procuses bx dx di si, fp:qword, rptr:wordFPMATH.ASMlocalshift:bytemovmovdi, word ptr rptrbx, wordptr fp[0]movmovmovandax,dx,cx,cx,word ptr fp[2]word ptr fp[4]dx7f80hshlmovsubsubcx,cl,ch,cl,1chch7ehjbemovsubleave_with_zeroch, 40ch, cljbmovmovsubalready-floorbyte ptr shift, chcl, chch, chshrdx, 1rcrrcrloopax, 1bx, 1fix;get float with extended;precision;get rid of sign and mantissa;portion;subtract bias (-1) from;exponent;is it greater than the;mantissa portion?;there is no fractional partfix:movre_position:shlrclrclloopbx, 1ax, 1dx, 1re_positionalready_floor:movmovmovsubword ptr [di][4], dxword ptr [di][2], axword ptr [di][0], bxax, ax;shift the number the amount;of times;indicated in the exponent;position as fixed pointcl, byte ptr shift341NUMERICAL METHODSmovfir_exit:retleave_with_one:leamovmovmovswrepjmpleave_with_zero:submovmovstoswrepjmpflrword ptr [di][6], axsi, word ptr onedi, word ptr rptrcx, 4fir_exitax, axcx, 4di, word ptr rptrshort fir_exitendp;; ******;flceil least integer greater than or equal to x;single precision;;flceilproc uses bx dx di si, fp:qword, rptr:wordshift:bytelocal342movmovdi, word ptr rptrbx, word ptr fp[0]mOVmovsuborororjemovandax, word ptr fp[2]dx, word ptr fp[4]cx, cxcx, bxcx, axcx, dxleave_with_zero;this is a zerocx, dx;get rid of sign and mantissacx, 7f80hq;portionshlmovcx, 1cl, ch;get float with extended;precisionFPMATH.ASMsubsubch, chcl, 7ehjbemovsubleave_with_onech, 40ch, cljbmovmovsubalready_ceilbyte ptr shift, chcl, chch, chshrdx, 1rcrrcrrcrax, 1bx, 1word ptr [di][6], 1loopfixcmpjeaddadcadcword ptr [di][6],0hnot_quite_enoughbx, 1ax, 0dx, 0;subtract bias (-1) from;exponent;is it greater than the;mantissa portion?;there is no fractional partfix:;shift the number the amount;of times indicated in the;exponentnot_quite_enough:movre_position:shlrclrclloopbx, 1ax, 1dx, 1re_positionalready_ceil:movmovmovsubmovword ptrword ptrword ptrax, axword ptr;put guard digits in MSW of;data type;position as fixedpoint;roundupcl, byte ptr shift[di][4], dx[di][2], ax[di][0], bx[di][6], axceil-exit:ret343NUMERICAL METHODSretleave_with_one:leamovmovmovswrepjmpleave_with_zero:submovmovstoswrepjmpsi, word ptr onedi, word ptr rptrcx, 4ceil_exitax, axcx, 4di, word ptr rptrshort ceil_exit; ******round proc;movmovmovcmpjbjnetestjejmpax,word ptr fp[0]bx,word ptr fp[2]dx,word ptr fp[4]ax,8000hround_exneeds_roundingbx,lround_exshort needs_roundingxorbx,lorbx,ljmpneeds_rounding:andaddadctestjemov344uses bx dx di, fp:qword, rptr:word;less than half;round to even if odd;and odd if even;round down if odd and up if;evenround_exdx,7fhbx,lhdx,0dx,80hrenormax, word ptr fp[4];if this is a one, there will;be an;overflowFPMATH.ASMandaddjoorjmprenorm:movandorround_ex:subround_exl:movmovmovmovsubmovretax,0ff80hax,80hover_flowdx,axshort round_exax,word ptr fp[4]ax,0ff80hdx,ax;get exponent and sign;kick it up one;get exponent and signax, axdi,word ptr rptrword ptr [di][0],axword ptr [di][2],bxword ptr [di][4],dxax, axword ptr [di][6], axover_flow:xormovax,axbx,axnotmovxorjmpround endp;return a quiet NAN if;overflowaxdx,axdx, 7fHshort round_exl;; ******;does a single-precision fabs;fp_absrepproc usessi di, fp0:dword, fpl:wordlocalflp0:qword,result:qwordxorleamovstoswax,axdi,word ptr flp0cx,4345NUMERICAL METHODSreplealeamovmovswinvokemovmovmovmovmovsi,word ptr fp0di,word ptr flp0[2]cx,2flabs, flp0, addr resultax, word ptr result[2]dx, word ptr result[4]di, word ptr fp1word ptr [di], axword ptr [di][2], dxretfp_absendp; ******; extended-precision absolute value (fabs);flabs proc uses bx cx dx si di, fp0:qword, result:wordmovmovmovmovmovmovandmovretflabs endpdi, word ptr resultax, word ptr fp0word ptr [di], axax, word ptr fp0[2]word ptr [di][2], axax, word ptr fp0[4]ax, 7fffh;strip sign, make positiveword ptr [di] [4] , ax;,.