Morgan - Numerical Methods (523161), страница 41
Текст из файла (страница 41)
The;arguments and a pointer to the result are passed on the stack.mullong proc uses ax dx es di,smultiplicand:dword, smultiplier:dword, result:wordmovdi,word ptr result;small model pointer is;nearmovax, word ptr smultiplicand[2];multiply multiplicand;high word299NUMERICAL METHODSmulmovmovword ptr smultiplier[2]word ptr [di][4], axword ptr [di] [6], dx;by multiplier high wordmovax, word ptr smultiplicand[2]mulmovaddadcwordwordwordword;multiply multiplicand;high word;by multiplier low wordmovax, word ptr smultiplicand[0]muladdadcadcwordwordwordwordmovax, word ptr smultiplicand[0]mulmovaddadcadcretwordwordwordwordwordptrptrptrptrptrptrptrptrsmultiplier[0][dil[2], ax[di][4], dx[di][6], 0smultiplier[2][di][2], ax[di][4], dx[di][6], 0ptr smultiplier[0]ptr [di][0], axptr [di][2], dxptr [di][4], 0ptr [di][6], 0;add any remnant carry;multiply multiplicand;low word;by multiplier high word;add any remnant carry;multiply multiplicand;low word;by multiplier low word;add any remnant carrymullong endp; ******;* Mu164 - Multiplies two unsigned quadword integers.
The;* procedure allows for a product of twice the length of the multipliers,;* thus preventing overflows.mu164 proc uses ax dx,multiplicand:qword, multiplier:qword, result:word300movdi,word ptr resultmovax, word ptr multiplicand[6]mulword ptr multiplier[6];multiply multiplicand;highword;by multiplier high wordFXMATH.ASMmovmovword ptr [di][12], axword ptr [di][14], dxmovax, word ptr multiplicand [6] ;multiply multiplicand;high word;by multiplier low wordword ptr multiplier[4]word ptr [di] [10], axword ptr [di][12], dxword ptr [di][14], 0;add any remnant carrymovmovaddadcmovmovmovaddadcadcax, word ptr multiplicand[6] ;multiply multiplicand;low wordword ptr multiplier[2];by multiplier high wordword ptr [di][8], axword ptr [di][10], dxword ptr [di][12], 0;add any remnant carryword ptr [di] [14], 0;add any remnant carrymovax, word ptr multiplicand[6]movmovaddjncadcadcadcwordwordword@fwordwordwordmovax, word ptr multiplicand[4]muladdadcadcwordwordwordwordmovax, word ptr multiplicand[4] ;multiply multiplicand;high wordword ptr multiplier[4];by multiplier high wordword ptr [di][8], axword ptr [di] [10], dxword ptr [di] [12], 0ptr multiplier[0]ptr [di][6], axptr [di][8], dxptr [di][10], 0ptr [di][12], 0ptr [di][14], 0;multiply multiplicand;low word;by multiplier high word;add any remnant carry@@:muladdadcadcptrptrptrptrmultiplier[6][di][10], ax[di][12], dx[di][14], 0;multiply multiplicand;low word;by multiplier low word301NUMERICAL METHODSadcword ptr [di] [14], 0movax, word ptr multiplicand[4]muladdadcjncadcadcadcwordwordword@fwordwordwordmovax, word ptr multiplicand[4]mulmovaddjncadcadcadcadcwordwordword@fwordwordwordwordmovax, word ptr multiplicand[2]muladdadcadcadcwordwordwordwordwordmovax, word ptr multiplicand[2]muladdadcjncadcadcadcwordwordword@fwordwordwordptr multiplier[2]ptr [di][6], axptr [di][8], dxptr [di][10], 0ptr [di][12], 0ptr [di][14], 0;multiply multiplicand;high word;by multiplier low word;add any remnant carry@@:ptr multiplier[0]ptr [di][4], axptr [di][6], dxptrptrptrptr[di][8],[di][10],[di][12],[di][14],0000;multiply multiplicand;high word;by multiplier low word;add any remnant carry@@:302ptr multiplier[6]ptr [di][8], axptr [di][10], dxptr [di][12], 0ptr [di][14], 0ptr multiplier[4]ptr [di][6], axptr [di][8], dxptr [di][10], 0ptr [di][12], 0ptr [di][14], 0;multiply multiplicand;low word;by multiplier high word;add any remnant carry;add any remnant carry;multiply multiplicand;low word;by multiplier low word;add any remnant carry;add any remnant carry;add any remnant carryFXMATH.ASM@@:movax, word ptr multiplicand[2]muladdadcjncadcadcadcadcwordwordword@fwordwordwordwordmovax, word ptr multiplicand[2]mulmovaddjncadcadcadcadcadcwordwordword@fwordwordwordwordwordmovax, word ptr multiplicand[0]muladdadcjncadcadcadcwordwordword@fwordwordwordmovax, word ptr multiplicand[0]muladdadcjncadcwordwordword@fwordptr multiplier[2]ptr [di][4], axptr [di][6], dxptrptrptrptr[di][8], 0[di][10], 0[di][12], 0[di][14], 0;multiply multiplicand;low word;by multiplier high word;add;add;add;addanyanyanyanyremnantremnantremnantremnantcarrycarrycarrycarry@@:ptr multiplier[0]ptr [di][2], axptr [di][4], dxptrptrptrptrptr[di][6], 0[di][8], 0[di][10], 0[di][12], 0[di][14], 0;multiply multiplicand;low word;by multiplier low word;add;add;add;add;addanyanyanyanyanyremnantremnantremnantremnantremnantcarrycarrycarrycarrycarry@@:ptr multiplier[6]ptr [di][6], axptr [di][8], dxptr [di][10], 0ptr [di] [12], 0ptr [di] [14], 0;multiply multiplicand;low word;by multiplier high word;add any remnant carry;add any remnant carry;add any remnant carry@@:ptr multiplier[4]ptr [di][4], axptr [di][6], dxptr [di][8], 0;multiply multiplicand;low word;by multiplier low word;add any remnant carry303NUMERICAL METHODS;add any remnant carry;add any remnant carry;add any remnant carryadcadcadcword ptr [di][10], 0word ptr [di][12], 0word ptr [di][l4], 0movax, word ptr multiplicand[0] ;multiply multiplicand;low word;by multiplier high wordword ptr multiplier[2]word ptr [di][2], axword ptr [di][4], dx@f;add any remnant carryword ptr [di][6], 0;add any remnant carryword ptr [di][8], 0;add any remnant carryword ptr [di][10], 0;add any remnant carryword ptr [di][12], 0;add any remnant carryword ptr [di][14], 0@@:muladdadcjncadcadcadcadcadc@@:movmulmovaddjncadcadcadcadcadcadcax, word ptr multiplicand[0] ;multiply multiplicand;low word;by multiplier low wordword ptr multiplier[0]word ptr [di][0], axword ptr [di][2], dx@f;add any remnant carryword ptr [di][4], 0;add any remnant carryword ptr [di][6], 0;add any remnant carryword ptr [di][8], 0;add any remnant carryword ptr [di][10], 0;add any remnant carryword ptr [di][12], 0;add any remnant carryword ptr [di][14], 0@@:retmu164 endp;******; classic multiplycmul proc uses bx cx dx si di, multiplicand:dword, multiplier:dword,product:wordlocal304numbits:byte,mltpcnd:qwordFXMATH.ASMreppushfcldsublealeamovmovswstoswstoswmovmovmovmovax,si,di,cx,axword ptr multiplicandword ptr mltpcnd2;clear upper wordsbx, axcx, axdx, axbyte ptr numbits, 32test_multiplier:shrword ptr multiplier[2], 1rcrword ptr multiplier,1jncdecrement_counteraddadcadcadcax,bx,cx,dx,decrement_counter:shlwordrclwordrclwordrclworddecjnzwordwordwordwordptrptrptrptrptrptrptrptrmltpcndmltpcnd[2]mltpcnd[4]mltpcnd[6]mltpcnd, 1mltpcnd[2], 1mltpcnd[4], 1mltpcnd[6],1byte ptr numbitstest_multiplierexit:movmovmovmovmovpopfretcmul endpdi, wordword ptrword ptrword ptrword ptrptr product[di], ax[di][2], bx[di][4], cx[di][6], dx305NUMERICAL METHODS; ******; classic multiply (slightly faster); one quad word by another, passed on the stack, pointers returned; to the results.: composed of shift and add instructionsprocuses bx cx dx si di, multiplicand:qword,fast_cmulmultiplier:qword, product:wordlocalreppushfcldsubmovleamovmovswnumbits:byteax,di,si,cx,axword ptr productword ptr multiplicand4;clear the productsubleamovdi, 8si, word ptr multiplierbyte ptr numbits, 40hsubmovmovmovax,bx,cx,dx.axaxaxaxtest_for_zero:testjnejmpword ptr [di], 1add-multipliershort shiftadd_multiplier:addadcadcadcax,bx,cx,dx,wordwordwordworddx,cx,bx,ax,1111shift:shrrcrrcrrcr306ptrptrptrptr[si][si][2][si][4][si][6];point to base of product;number of bitsFXMATH.ASMrcrrcrrcrrcrwordwordwordworddecjzjmpbyte ptr numbitsexitshort test_for_zeromovmovmovmovwordwordwordwordptrptrptrptr[di][6], 1[di][4], 1[di][2], 1[di] [0], 1exit:ptrptrptrptr[di][8],[di][10],[di][12],[di][14],axbxcxdxpopfretfast_cmul endp; ******; booth; unsigned multiplication technique based upon the booth method;;booth procproduct:wordlocaluses bx cx dx, multiplicand:dword, multiplier:dword,mltpcnd:qwordpushfcldrepsublealeamovmovswstoswstoswax,si,di,cx,movmovmovclcbx, axcx, axdx, axaxword ptr multiplicandword ptr mltpcnd2;clear upper words307NUMERICAL METHODScheck_carry:jctestjzcarry_setword ptr multiplier, 1shift_multiplicandsub_multiplicand:ax,subbx,sbbcx,sbbdx,sbbwordwordwordwordshift_multiplicand:wordshlwordrclwordrclwordrclorjnzorjnzjmpptrptrptrptrptrptrptrptr;test bit 0mltpcndmltpcnd[2]mltpcnd[4]mltpcnd[6]mltpcnd, 1mltpcnd[2], 1mltpcnd[4], 1mltpcnd[6], 1word ptr multiplier[2], 0shift_multiplierword ptr multiplier, 0shift_multipliershort exit;early-out mechanismshift_multiplierword ptr multiplier[2], 1shrword ptr multiplier, 1rcrshort check_carryjmpexit:movmovmovmovmovdi, wordword ptrword ptrword ptrword ptrptr product[di], ax[di][2], bx[di][4], cx[di][6], dxpopfretcarry_set:testjnzword ptr multiplier, 1shift-multiplicandadd_multiplicand:308;test bit 0FXMATH.ASMaddadcadcadcjmpax, word ptr mltpcndbx, word ptr mltpcnd[2]cx, word ptr mltpcnd[4]dx, word ptr mltpcnd[6]short shift-multiplicandbooth endp; ******; bit pair encoding; unsigned corollary to the booth methodbit_pair procproduct:wordlocaluses bx cx dx, multiplicand:dword, multiplier:dword,mltpcnd:qwordpushfcldrepsublealeamovmovswstoswstoswax,si,di,cx,movmovmovclcbx, axcx, axdx, axcheck_carry:jctestjztestjnzjmpaxword ptr multiplicandword ptr mltpcnd2;clear upper wordscarry_setword ptr multiplier, 1shiftorsub;test bit n-1;test bit 0word ptr multiplier, 2sub_multiplicandadd_multiplicand;test bit 1309NUMERICAL METHODSshiftorsub:testjzword ptr multiplier, 2shift_multiplicandsubx2_multiplicand:subsbbsbbsbbax,bx,cx,dx,wordwordwordwordptrptrptrptrmltpcndmltpcnd[2]mltpcnd[4]mltpcnd[6]sub_multiplicand:subsbbsbbsbbax,bx,cx,dx,wordwordwordwordptrptrptrptrmltpcndmltpcnd[2]mltpcnd[4]mltpcnd[6]shift_multiplicand:shlrclrclrclwordwordwordwordptrptrptrptrmltpcnd, 1mltpcnd[2],1mltpcnd[4], 1mltpcnd[6], 1shlrclrclrclwordwordwordwordptrptrptrptrmltpcnd, 1mltpcnd[2], 1mltpcnd[4], 1mltpcnd[6], 1orjnzorjnzjmpword ptr multiplier[2], 0shift_multiplierword ptr multiplier, 0shift_multipliershort exitshift_multiplier:shrrcrshrrcrjmpword ptr multiplier[2], 1word ptr multiplier, 1word ptr multiplier[2],1word ptr multiplier, 1short check_carry;cheap-inline multiplyexit:movmov310;test bit 1di, word ptr productwordptr [di], axFXMATH.ASMmovmovmovword ptr [di][2], bxword ptr [di][4], cxword ptr [di][6], dxpopfretcarry_set:testjnzjmpaddx2_multiplicand:addadcadcadcadd_multiplicand:addadcadcadcjmpword ptr multiplier, 1addorsubx2short addor subxlax,bx,cx,dx,wordwordwordwordptrptrptrptrmltpcndmltpcnd[2]mltpcnd[4]mltpcnd[6];cheap in_line multiplyax, word ptr mltpcndbx, word ptr mltpcnd[2]cx, word ptr mltpcnd[4]dx, word ptr mltpcnd[6]short shift_multiplicandaddorsubx2:testjnzjmpword ptr multiplier, 2shift_multiplicandshort addx2_multiplicand;test bit 1addorsubx1:testjnzjmpword ptr multiplier, 2sub_multiplicandshort add_multiplicand;test bit 1bit_pair endp; ******;;;;;;classic divideOne quadword by another, passed on the stack, pointers returnedto the results.Composed of shift and sub instructions.Returns all zeros in remainder and quotient if attempt is made to dividezero.
Returns all ff's inquotient and dividend in remainder if divide by311NUMERICAL METHODS;zero is attempted.uses bx cx dx si di, dvdnd:qword, dvsr:qword,cdiv procqtnt:word, rmndr:wordreppushfcldsubmovmovstoswcx, 4si, word ptr dvdnddi, word ptr qtntrepmovleamovmovswsubmovsubmovmovmovdi,si,ax,bx,cx,dx,shlrclrclrclwordwordwordwordrclrclrclrclax,bx,cx,dx,ax, axdi, word ptr qtntcx, 4;clear the quotient;dvdnd and qtnt share same;memory space864axaxaxax;number of bitsshift:compare:cmpjbcmpjbcmpjbcmpjb312ptrptrptrptr[di], 1[di][2], 1[di][4], 1[di][6], 11111dx, word ptrtest_for_endcx, word ptrtest_for_endbx, word ptrtest_for_endax, word ptrtest_for_enddvsr[6]dvsr[4]dvsr[2]dvsr[0];shift dividend into;the remainderFXMATH.ASMsubsbbsbbsbbaddadcadcadctest_for_end:decjnzmovmovmovmovmovax, wordbx, wordcx, worddx, wordword ptrword ptrword ptrword ptrptr dvsrptr dvsr[2]ptr dvsr[4]ptr dvsr[6][di], 1[di][2], 0[di][4], 0[di][6], 0sishiftdi, wordword ptrword ptrword ptrword ptrptr rmndr[di], ax[di][2], bx[di][4], cx[di][6], dxexit:cdivpopfretendp;******;div32;32 by 32 bit divide;arguments are passed on the stack along with pointers to the;quotient and remainderdiv32 proc uses ax dx di si,dvdnd:dword, dvsr:dword, qtnt:word, rmndr:wordreplocalworkspace[8]:wordsubmovmovlealeamovswmovax,dx,cx,si,di,axax2word ptr dvdndword ptr workspacecx, 2313NUMERICAL METHODSlealeamovswmovdi, word ptr qtntcmpjnecmpjnejmpword ptr dvdnd, axdo_divideword ptr dvdnd[2],axdo_dividezero_divrepdo_divide:cmpjnecmpjesi, word ptr dvsrdi, word ptr workspace[4]word ptr dvsr[2],axshiftword ptr dvsr, axdiv_by_zeromovbx, word ptr rmndrmovax, word ptr dvdnd[2]divmovmovdivmovmovxormovjmpword ptr dvsrword ptr [di][2],axax, word ptr dvdndword ptr dvsrword ptr [di],axword ptr [bx],dxax,axword ptr [bx] [2],axexitshrword ptr dvdnd[2], 1rcrshrrcrcmpjneword ptrword ptrword ptrword ptrshiftmovax, word ptr dvdndmovdx, word ptr dvdnd[2];zero dividend;see if it is small enough;check for divide by zero;as long as dx is zero,;there is;no overflow possible in;this divisionshift:;normalize both dvsr and;dvdnddvdnd[0], 1dvsr[2], 1dvsr[0], 1dvsr[2],axdivide:314;since MSB of dvsr is a;one, there;is no overflow possibleFXMATH.ASMheredivmovget_remainder:movleaword ptr dvsrword ptr [di] [0], axbx, didi, word ptr workspace[8]reconstruct:movmulmovmovmovmuladdax, wordword ptrword ptrword ptrax, wordword ptrword ptrmovmovsubsbbax,dx,ax,dx,jncdiv_exmovmovsubsbbax, worddx, wordword ptrword ptrjmpshort reconstructmovdi, word ptr rmndrmovmovclcword ptr [di], axword ptr [di][2], dxptr workspace[4][bx][di][0], ax[di][2], dxptr workspace[6][bx][di][2], ax;approximatequotient;quotient;test first approximation;of quotient by multiplying;multiplying it by the dvsr;and comparing it with the;dvdnd;low word of multiplicand;by low word of multiplier;high word of multiplicand;byword ptr workspace[0]word ptr workspace[2]word ptr [di] [0]word ptr [di] [2];good or overflows;overflow, decrement approx;quotientptr [bx]ptr [bx][2][bx], 1[bx][2], 0div_ex:;the result is a good;quotient and remainderexit:retdiv_by_zero:315NUMERICAL METHODSnotmovmovstcjmpzero_div:movmovstcjmpdiv32 endpaxword ptr [di][0], axword ptr [di][2], axexitword ptr [di][0], axword ptr [di][2], axexit; ******;The dividend and divisor are passed on the stack;the doubleword fixed;point result is returned in DX:AX.