Morgan - Numerical Methods (523161), страница 43
Текст из файла (страница 43)
******;does a floating-point compare;returns with answer in axproc uses si di,fp_compfp0:dword, fpl:dwordlocal346flp0:qword, flp1:qwordFPMATH.ASMxorleamovrep stoswax,axdi,word ptr flp0cx,4leamovrep stoswdi,word ptr flplcx,4lealeamovrep movswsi,word ptr fp0di,word ptr flp0[2]cx,2lealeamovrep movswsi,word ptr fp1di,word ptr flp1[2]cx,2invokeretfp_campflcomp, flp0, flp1endp;: ***;internal routine for comparison of floating-point values;flcompproc usescx si di,fp0:qword, fpl:qwordpushfstdlealeatestjetestjesi,word ptr fp0[4]di,word ptr fp1[4]word ptr fp0[4],8000hplus_lword ptr fpl[4],8000hsecond_gtrxchgdi,si;is the first positive.;yes;second not negative, there;fore greater347NUMERICAL METHODScompare:movrepecmpswjajbjmp;plus_l:testjejmp;second_gtr:movjmpfirst_gtr:movjmpboth-same:subfpcmp_ex:popfretflcompendpcx,3first_gtrsecond_gtrshort both-sameword ptr fp1[4],8000hcomparefirst_gtrax,-1short fpcmp_exax,1short fpcmp_exax,ax;; ******;fp_subproc uses si di,fp0:dword, fp1:dword, rptr:wordlocalreppushfcldxorleamovstoswrepleamovstosw348flp0:qword, flp1:qword, result:qwordax,axdi,word ptr resultcx,4di,word ptr flp0cx,4FPMATH.ASMleamovr e p stoswdi,word ptr flp1cx,4lealeamovr e p movswsi,word ptr fp0di,word ptr flp0[2]cx,2replealeamovmovswsi,word ptr fp1di,wordptr flp1[2]cx,2invokeflsub, flp0, flp1, addr result;pass pointer to called;routineinvokeleamovmovmovswpopfretfp_subendpround, result, addr resultsi,word ptr result[2]di,rptrcx,2;; ***;internal;;flsub procuses bx cx dx si di,fp0:qword, fp1:qword, rptr:wordxorword ptr fp1[4],8000h;complement sign bitinvokefladd, fp0, fp1, rptr;pass pointer to called;routineretflsub endp349NUMERICAL METHODS;;******fp_addproc uses bx cx dx si di,fp0:dword, fpl:dword, rptr:wordlocalpushfcldxorleamovrep stoswflp0:qword, flpl:qword, result:qwordax,axdi,word ptr resultcx,4leamovrep stoswdi,word ptr flp0cx,4leamovrep stoswdi,word ptr flp1cx,4lealeamovrep movswsi,word ptr fp0di,word ptr flp0[2]cx,2lealeamovmovswsi,word ptr fp1di,word ptr flp1[2]cx,2invokefladd, flp0, flp1, addr resultinvokeround, result, addr resultrepleamovmovmovswpopfretfp_addendp350si,word ptr result [2]di,rptrcx,2FPMATH.ASM***;internal;fladd proclocaluses bx cx dx si di,fp0:qword, fp1:qword, rptr:wordopa:qword, opb:qword, signa:byte,signb:byte, exponent:byte, sign:byte,flag:byte, diff:byte, sign0:byte, sign1:byte,exp0:byte, exp1:bytepushfstd;decrementxorax,ax;clear appropriate variablesdi,word ptr opa[6]leamovcx, 4stoswword ptr [di]repleadi,word ptr opb[6]movcx,4stoswword ptr [di]repmovbyte ptr sign0, almovbyte ptr sign1, almovbyte ptr flag,almovbyte ptr sign,alchk_fp0:submovandcmpjnemovcmpjnemovcmpjnebx, bxax, word ptr fp0[4]ax, 7fffhax, bxchk_fplax, word ptr fp0[2}ax, bxchk_fplax, word ptr fp0ax, bxchk_fpl;larger operand;smaller operand;clear sign;check for zero351NUMERICAL METHODSleajmpchk_fp1:movandcmpjnemovcmpjnemovcmpjneleasi,word ptr fp1[6]short leave_with_other;return other addendax, word ptr fp1[4]ax, 7fffhax, bxdo_addax, word ptr fp1[2]ax, bxdo_addax, word ptr fp1ax, bxdo_addsi,word ptr fp0[6];check for zero;return other addend;*******************leave_with_other:movdi,word ptr rptr;one of the operands was zeroadddi,6;the other operand is the;onlymov;answercx,4movswrepfp_addexjmp;*******************do_add:lealeasi,word ptr fp0bx,word ptr fp1movshlrclmovax,word ptr [si][4]ax,:byte ptr sign0, 1byte ptr exp0, ah;fp0;dump the sign;collect the sign;get the exponentmovshlrclmovsubdx,word ptr [bx][4]dx,1byte ptr sign1, 1byte ptr exp1, dhah, dh;fPl;get signmovbyte ptr diff, ah;and now the differencerestore-missing-bit:352;and the exponent;set up operandsFPMATH.ASMandorword ptr fp0[4], 7fhword ptr fp0[4], 80hmovmovmovandormovax, wordbx, worddx, worddx,7fhdx,80hword ptrptr fp1ptr fp1[2]ptr fp1[4]fp1[4], dxfind_largest:cmpjetestjejmpbyte ptr diff,0cmp_restbyte ptr diff,80hnuma_biggershort numb_biggercmp_rest:cmpjajbdx, word ptr fp0[4]numb_biggernuma_biggercmpjajbbx, word ptr fp0[2]numb_biggernuma_biggercmpjbax, word ptr fp0[0]numa_biggernumb_bigger:submovnegmovcmpjnaax, axal,byte ptr diffalbyte ptr diff,alal,40in_range;*******************si, word ptr fp1[6]lealeave-with-largest:movdi, word ptr rptradddi,6movcx,4;test fornegative;save difference;do range test;this is an exit!!!!!;this is a range error;operands will not line up;for a valid addition;leave with largest operand;that is where the signifi353NUMERICAL METHODSmovswfp_addexjmprange_errora:leasi,word ptr fp0[6]short leave_with_largestjmp;*******************repin_range:movmoval,byte ptr exp1byte ptr exponent,almovmovmovmoval, byte ptr sign0byte ptr signb, alal, byte ptr sign1signa, alleasi, word ptr fp1[6]leamovmovswdi, word, ptr opa [6]cx, 4repsignb_positive:leajmpsi, word ptr fp0[4]shift_into_positionnuma_bigger:submovcmpjaeax, axal,byte ptr diffal,40range_errora354movmOVal,byte ptr exp0byte ptr exponent,almOVmovmovmoval, byte ptr sign1byte ptr signb, alal, byte ptr sign0byte ptr signa, alleasi, word ptr fp0[6];cance;is anyway;save exponent of largest;value;load opa with largest;operand;set to load opb;do range test;save exponent of largest;value;1oad opa with largestFPMATH.ASM;operandrepleamovmovswdi, word ptr opa[6]cx,4leasi, word ptr fp1[4]shift_into_position:xorax,axmovbx,4movcl,3movah,byte ptr diffshrax,clmovshrcx,5hal,clsubbl,ahleaadd;set to load opb;align operands;ah contains # of bytes, al #;of bits;reset pointer below initial;zerosdi,byte ptr opbdi,bxmovincload_operand:movsbloopcx,bxcxmovxororjeshift_operand:shrrcrrcrrcrloopcl,alch,chcx,cxend_shiftword ptr opb[6],1word ptr opb[4],1word ptr opb[2],1word ptr opb[0],lshift_operandend_shift:movcmpjeal, byte ptr signaal, byte ptr signbjust_addload_operand355NUMERICAL METHODS;signs alikeopb_negative:notnotnotnegjcaddadcadcjmp;signs disagreeword ptr opb[6];do2's complementword ptr opb[4]word ptr opb[2]word ptr opb[0]just_addword ptr opb[2],1word ptr opb[4],0word ptr opb[6],0just_addjust_add:invokeadd64, opa, opb, rptrhandle_sign:movmovmovmovsi,dx,bx,ax,wordwordwordwordptr rptrptr [si][4]ptr [si][2]ptr [si][0]norm:subcx, cxax,cxcmpjnenot_zerobx,cxcmpjnenot-zerodx,cxcmpjnenot_zerowrite_resultjmpnot_zero:movcx,64dx,0hcmprotate_result_leftjedh,00hcmpjnerotate_result_righttestdl,80hrotate_result_leftjeshort done_rotatejmprotate_result_right:356;exit with a zeroFPMATH.ASMshrrcrrcrincdX,lbx,lax,1byte ptr exponenttestdx,0ff00hdone_rotatejelooprotate_result_rightrotate_result_left:shlax,1rclbx,lrcldx,ldecbyte ptr exponenttestjneloopdone_rotate:andshlorshrmovdx,80hdone_rotaterotate_result_leftorjeorfix_sign:movorjeorwrite_result:movmovmovmovsubmovfp_addex:popfretfladd endpcl, clfix_signdx,8000hdx,7fhdx, 1dh, byte ptr exponentdx, 1cl, byte ptr signcl,byte ptr signacl, clwrite-resultdx,8000h;decrement exponent with each;shift;decrement exponent with each;shift;insert exponent;sign of the result of the;operation;sign of the larger operand;negativedi,word ptr rptrword ptr [di],axword ptr [di][2],bxword ptr [di][4],dxax,axword ptr [di][6],ax357NUMERICAL METHODS;******;fp_divproc cuses si di,fp0:dword, fp1:dword, rptr:wordlocalpushfcldxorleamovrep stoswflp0:qword, flp1:qword, result:qwordax,axdi,word ptr resultcx,4leamovr e p stoswdi,word ptr flp0cx,4leamovrep stoswdi,word ptr flp1cx,4lealeamovrep movswsi,word ptr fp0di,word ptr flp0[2]cx,2lealeamovrep movswsi,word ptr fp1di,word ptr flp1[2]cx,2358invokefldiv, flp0, flp1, addr resultinvokeround, result, addr resultleamovmovmovswsi,word ptr result[2]di,rptrcx,2;pass pointer to called;routineFPMATH.ASMpopfretfp_divendp; ***;fldiv procCuses bx cx dx si di,fpO:qword,fp1:qword, rptr:wordlocalqtnt:qword, sign:byte, exponent:byte, rmndr:qwordpushfstdxorax,axmovbyte ptr sign, allealeasi,word ptr fp0bx,word ptr fp1movshlandjnejmpax,word ptr [si][4]ax,1ax,0ff00hchk_breturn_infinite;infinitymovsh1andjnejmpdx,word ptr [bx][4]dx,ldx,0ff00hb_notzdivide_b_zero;begin error and situation;checking;name a pointer to each fp;check for zerochk_b:;infinity, divide by zero is;undefinedb_notz:cmpjnejmpcheck-identity:movadddx,0ff00hcheck_identitymake_zero;divisor is infinitedi,bxdi,4;will decrement selves359NUMERICAL METHODSaddmovrepecmpswjnemovmovmovmovmovmovmovsubmovjmpnot_same:lealeasubaddsi,4cx,3not-same;these guys are the sameax,word ptr dgt[8];return a onebx,word ptr dgt[10]dx,word ptr dgt[12]di,word ptr rptrword ptr [di],axword ptr [di][2],bxword ptr [di][4],dxax,axword ptr [di][6],axfldivex;get exponents;reset pointerssi,word ptr fp0bx,word ptr fp1ah,dhah,77hmovbyte ptr exponent,ahmovdx, word ptr [si][4]ordx, dxjnsa_plusnotbyte ptr signa_plus:movdx,word ptr [bx][4]ordx, dxjnsrestore_missing_bitnotbyte ptr signrestore-missing-bit:360andorword ptr fp0[4], 7fhword ptr fp0[4],80hmovandorcmpdx,dx,dx,dx,jaincshrstore_dvsrbyte ptr exponentword ptr fp0[4], 1word ptr fp1[4]7fh80hword ptr fp0[4];add exponents;subtract bias minus two;digits;save exponent;check sign;line up operands for divi;sion;see if divisor is greater;thanFPMATH.ASMrcrrcrstore_dvsr:movdivide:invokemovmovsubword ptr fp0[2], 1word ptr fp0[0], 1word ptr fp1[4], dxdiv64, fp0, fp1, addr fp0dx, word ptr fp0[2]bx, word ptr fp0[0]ax, axsubcx,cxax,cxcmpjnenot_zerobx,cxcmpnot-zerojnedx,cxcmpjnenot_zerofix_signjmpnot_zero:movcx,64dx,0hcmprotate_result_leftjedh,00hcmprotate_result_rightjnedl,80htestrotate_result_leftjeshort done_rotatejmprotate_result_right:dx,lshrbx,lrcrax,1rcrdx,0ff00htestdone_rotatejebyte ptr exponentinc;exit with a zero;decrement exponent with each;shiftrotate_result_rightlooprotate_result_left:word ptr qtnt,1shlrclax,1rclbx,lrcldx,ldx,80htest361NUMERICAL METHODSjnedecloopdone_rotate:andshlorshrmovorjeorfix-sign:movmovmovmovsubmovfldivex:popfretreturn_infinite:submovnotmovandjmpdivide_by_zero:subnotjmpmake_zero:xordone_rotatebyte ptr exponent;decrement exponent with each;shiftrotate_result_leftdx,7fhdx,1dh, byte ptr exponentdx, 1cl,byte ptr signcl,clfix_signdx,8000h;insert exponentdi,word ptr rptrword ptr [di],axword ptr [di][2],bxword ptr [di][4],dxax,axword ptr [di][6],axax, axbx, axaxdx, axdx, 0f80hshort fix_sign;infinityax,axaxshort finish-errorax,ax;positive zerofinish-error:movaddmovstosrep362di,word ptr rptrdi,6cx,4word ptr [di]FPMATH.ASMshort fldivexjmpfldiv endp:; ******;:fp_mulproc cuses si di,fp0:dword, fp1:dword, rptr:wordlocalflp0:qword, flp1:qword, result:qwordreppushfcldxorleamovstoswdi,word ptr flp0cx, 4repleamovstoswdi,word ptr flp1cx, 4repleamovstoswsi,word ptr fp0di,word ptr flp0[2]cx, 2replealeamovmovswsi,word ptr fp1di,word ptr flp1[2]cx,2replealeamovmovswinvokeflmul, flp0, flp1, addr resultinvokeround, result, addr resultleamovsi,word ptr result [2]di,rptrax,axdi,word ptr resultcx,4;pass pointer to called;routine363NUMERICAL METHODSmovmovswpopfretfp_mulendpcx,2rep;flmul proclocalreppushfstdsubmovleamovstoswlealeamovshlandjnejmpis_a_inf:cmpjnejmpis_b_zero:movshlandjnzjmpis_b_inf:cmpjne364C uses bx cx dx si di,fp0:gword, fp1:gword, rptr:wordresult[6]:word,sign:byte,exponent:byteax,axbyte ptr sign,aldi,word ptr result[10]cx,6si,word ptr fp0bx,word ptr fp1ax,word ptr [si][4]ax,1ax,0ff00his_a_infmake_zeroax,0ff00his_b_zeroreturn_infinitedx,word ptr [bx][4]dx,ldx,0ff00his_b_infmake_zerodx,0ff00hget_exp;name a pointer to each fp;check for zero;zero exponent;multiplicand is infinite;check for zero;zero exponentFPMATH.ASMjmp;get_exp:subaddmovmovorjnsnota_plus:movorjnsnotreturn-infinite;multiplicand is infiniteah, 77hah, dhbyte ptr exponent,ah;add exponents;save exponentdx,word ptr [si][4]dx, dxa_plusbyte ptr signdx,word ptr [bx][4]dx, dxrestore_missing_bitbyte ptr signrestore_missing_bit:andwordorwordandwordorwordptrptrptrptrfp0[4],fp0[4],fp1[4],fp1[4],7fh80h7fh80h;remove the sign and exponent;and restore the hidden bitinvokemu164a, fp0, fp1, addr result ;multiplymovmovmovdx,word ptr result [10]bx,word ptr result[8]ax,word ptr result[6]subcmpjnecmpjnecmpjnecnejnejmpnot_zero:movcmpjecmpcx,cxword ptr result[4], cxnot_zeroax,cxnot_zerobx,cxnot_zerodx,cxnot_zerofix_sign;exit with a zerocx,64dx,0hrotate_result_leftdh,00h365NUMERICAL METHODSrotate_result_rightjnetestdl,80hrotate_result_leftjeshort done_rotatejmprotate_result_right:shrdx,lrcrbx,lrcrax,1dx,0ff00htestdone_rotatejeincbyte ptr exponentlooprotate_result_rightrotate_result_left:shlword ptr result[2], 1rclword ptr result[4], 1rclax,1rclbx,lrcldx,ltestdx,80hjnedone_rotatedecbyte ptr exponentloopdone_rotate:andshlorshrmovorjeorfix_sign:movmovmovmovsubmovfp_mulex:popfret:366;decrement exponent with each;shift;decrement exponent with each;shiftrotate_result_leftdx,7fhdx, 1dh, byte ptr exponentdx, 1cl,byte ptr signcl,clfix_signdx,8000hdi,word ptr rptrword ptr [di], axword ptr [di][2], bxword ptr [di][4], dxax, axword ptr [di][6], ax;insert exponentFPMATH.ASMreturn_infinite:submovnotmovandjmpmake_zero:xorfinish_error:movaddmovstosrepjmpflmul endpax, axbx, axaxdx, axfix,0f80hshort fix_sign;infinityax,axdi, word ptr rptrdi, 6cx, 4word ptr [di]short fp_mulex;******; cylinder- finds the volume of a cylinder using the floatingpoint rou;tines in this module.volume = pi * r * r h;.dataqword404956c10000Hpi.code;cylinderproc uses bx cx dx si di,radius:dword, height:dword, area:wordlocalresult:qword, r:qword, h:qwordsubax, axcx, 4di,word ptr rrepmovleastoswcx, 4di, word ptr hrepmovleastoswmovax, word ptr radius[0];clear space for intermediate;variables;move IEEE format to extended;format367NUMERICAL METHODSmovmovmovmovmovmovmovdx, word ptr radius[2]word ptr r[2], axword ptr r[4], dxax, word ptr height[0]dx, word ptr height[2]word ptr h[2], axword ptr h[4], dxinvokeflmul, r, r, addr resultinvokeflmul, pi, result, addr resultinvokeflmul, h, result, addr resultinvokeround, result, addr result;do r squared;multiply result by pi;multiply by height;round the resultmovmovdi, word ptr areaax, word ptr result[2]movmovmovdx, word ptr result[4]word ptr [di],axword ptr [di][2],dx;move result back to IEEE;formatretcylinder endp; ******;fixed-point support for floating-point routines; ******;Multiplies operands by ten, returning result in multiplicand;and overflow byte in ax.