AnsichtenInhaltsverzeichnis Mathe: Integer8
Mathematische Basis-Operationen für 8-Byte-Integer + - * /
Var1&1 Bedeutet erster und Zweiter Teil der Variable, die als Doppelwort im Speicher abgelegt wird. EDX:EAX Schreibweise um anzuzeigen daß das Resultat aus 2 Registern gebildet wird +% Bedeuten in der Operation wird das Cary-Flag Berücksichtigt Type welcher die Informationen für ein Integer8 trägt. Dies ist Vergleichbar mir dem Wert AL und AH die beide zusammen AX ergeben. BigInt1 AS Long ' Ist LowTeil, Vergleichbar mit AL BigInt2 AS Long ' Ist HighTeil, Vergleichbar mit AH End Type Integer8 struc Big1 DD ? Big2 DD ? Integer8 ends Basis-Operationen Float+ - * /;=== +, Addition ;=== Add = Val1 + Val2 MOV EAX, [ESP+4] ; EAX = Var1&1 MOV EDX, [ESP+8] ; EDX = Var1&2 ADD EAX, [ESP+12] ; EAX = EAX + Var2&1 ADC EDX, [ESP+16] ; EDX = EDX +% Var2&1 ;@CheckOverflow INTO ;=== -, Subtraktion ;=== Sub = Val1 - Val2 MOV EAX, [ESP+4] ; EAX = Var1&1 MOV EDX, [ESP+8] ; EDX = Var1&2 SUB EAX, [ESP+12] ; EAX = EAX - Var2&1 SBB EDX, [ESP+16] ; EDX = EDX -% Var2&1 ;@CheckOverflow INTO ;=== *, Multiplikation ;=== Mul = Val1 * Val2 MOV EBX, Val2 ; EBX = Val2 MOV EAX, Val1 ; EAX = Val2 MUL EAX, EBX ; EAX = EAX * EBX ;@CheckOverflow ;=== /, Division (Über Float mit Rundung) ;=== Div = Val1 / Val2 MOV EBX, Val2 ; EBX = Val2 MOV EAX, Val1 ; EAX = Val2 DIV EAX, EBX ; EAX = EAX / EBX ; ; EDX = EAX Mod EBX ;@CheckOverflow ;=== DIV, Division (Ganzzahlig ohne Rundung) ;=== Div = Val1 DIV Val2 MOV EBX, Val2 ; EBX = Val2 MOV EAX, Val1 ; EAX = Val2 DIV EAX, EBX ; EAX = EAX / EBX ; ; EDX = EAX Mod EBX ;@CheckOverflow ;=== MOD, Modulo Divisions Rest ;=== Mod = Val1 MOD Val2 MOV EBX, Val2 ; EBX = Val2 MOV EAX, Val1 ; EAX = Val2 DIV EAX, EBX ; EAX = EAX / EBX ; ; EDX = EAX Mod EBX MOV EAX, EDX ; EAX = Val2 ;@CheckOverflow
.386 .model small,pascal Integer8 struc Big1 DD ? Big2 DD ? Integer8 ends .code ;----------------------------------------------------------------------------- ;void pascal quadinc(Integer8* z, Integer8 x) ;compute z=z+x QUADINC proc z:ptr, x:qword MOV EAX,(x).Big1 MOV EDX,(x).Big2 MOV EBX,z ADD [EBX].Big1,EAX ADC [EBX].Big2,EDX ;----------------------------------------------------------------------------- ;void pascal quadinca(Integer8* z, Integer8* x) ;compute z=z+x public QUADINCA QUADINCA proc z:ptr, x:ptr MOV EBX,x MOV EAX,[EBX].Big1 MOV EDX,[EBX].Big2 MOV EBX,z ADD [EBX].Big1,EAX ADC [EBX].Big2,EDX ;----------------------------------------------------------------------------- ;void pascal quaddec(Integer8* z, Integer8 x) ;compute z=z-x public QUADDEC QUADDEC proc z:ptr, x:qword MOV EAX,(x).Big1 MOV EDX,(x).Big2 MOV EBX,z SUB [EBX].Big1,EAX SBB [EBX].Big2,EDX ;----------------------------------------------------------------------------- ;void pascal quaddeca(Integer8* z, Integer8* x) ;compute z=z-x public QUADDECA QUADDECA proc z:ptr, x:ptr MOV EBX,x MOV EAX,[EBX].Big1 MOV EDX,[EBX].Big2 MOV EBX,z SUB [EBX].Big1,EAX SBB [EBX].Big2,EDX ;----------------------------------------------------------------------------- ;void pascal quadadd(Integer8* z, Integer8 x, Integer8 y) ;compute z=x+y public QUADADD QUADADD proc z:ptr, x:qword, y:qword MOV EAX,(x).Big1 MOV EDX,(x).Big2 ADD EAX,(y).Big1 ADC EDX,(y).Big2 MOV EBX,z MOV [EBX].Big1,EAX MOV [EBX].Big2,EDX ;----------------------------------------------------------------------------- ;void pascal quadadda(Integer8* z, Integer8* x, Integer8* y) ;compute z=x+y public QUADADDA QUADADDA proc z:ptr, x:ptr, y:ptr MOV EBX,x MOV EAX,[EBX].Big1 MOV EDX,[EBX].Big2 MOV EBX,y ADD EAX,[EBX].Big1 ADC EDX,[EBX].Big2 MOV EBX,z MOV [EBX].Big1,EAX MOV [EBX].Big2,EDX ;----------------------------------------------------------------------------- ;void pascal quadsub(Integer8* z, Integer8 x, Integer8 y) ;compute z=x-y public QUADSUB QUADSUB proc z:ptr, x:qword, y:qword MOV EAX,(x).Big1 MOV EDX,(x).Big2 SUB EAX,(y).Big1 SBB EDX,(y).Big2 MOV EBX,z MOV [EBX].Big1,EAX MOV [EBX].Big2,EDX ;----------------------------------------------------------------------------- ;void pascal quadsuba(Integer8* z, Integer8* x, Integer8* y) ;compute z=x-y public QUADSUBA QUADSUBA proc z:ptr, x:ptr, y:ptr MOV EBX,x MOV EAX,[EBX].Big1 MOV EDX,[EBX].Big2 MOV EBX,y SUB EAX,[EBX].Big1 SBB EDX,[EBX].Big2 MOV EBX,z MOV [EBX].Big1,EAX MOV [EBX].Big2,EDX ;----------------------------------------------------------------------------- ;void pascal quadmult(Integer8* z, Integer8 x, Integer8 y) ;compute z=x*y public QUADMULT QUADMULT proc z:ptr, x:qword, y:qword MOV EAX,(x).Big1 MOV EBX,EAX MUL (y).Big2 XCHG EAX,EBX MOV ECX,(y).Big1 MUL ECX ADD EBX,EDX XCHG EAX,ECX MUL (x).Big2 ADD EAX,EBX MOV EBX,z MOV [EBX].Big1,ECX MOV [EBX].Big2,EAX RET QUADMULT endp ;----------------------------------------------------------------------------- ;void pascal quadmulta(Integer8* z, Integer8* x, Integer8* y) ;compute z=x*y public QUADMULTA QUADMULTA proc uses ESI, z:ptr, x:ptr, y:ptr MOV EBX,x MOV ESI,[EBX].Big1 MOV ECX,[EBX].Big2 MOV EBX,y MOV EAX,[EBX].Big2 MOV EBX,[EBX].Big1 MUL ESI XCHG EAX,ECX MUL EBX ADD ECX,EAX MOV EAX,EBX MUL ESI ADD EDX,ECX MOV EBX,z MOV [EBX].Big1,EAX MOV [EBX].Big2,EDX RET QUADMULTA endp ;----------------------------------------------------------------------------- ;void pascal quaddiv(Integer8* z, Integer8 x, Integer8 y) ;compute z=x/y public QUADDIV QUADDIV proc uses ESI EDI, z:ptr, x:qword, y:qword XOR EDI,EDI ;sign MOV EAX,(x).Big1 MOV EDX,(x).Big2 or EDX,EDX JNS quaddiv1 INC EDI NEG EAX ADC EDX,0 NEG EDX MOV (x).Big2,EDX MOV (x).Big1,EAX quaddiv1: MOV EBX,(y).Big1 MOV ESI,(y).Big2 or ESI,ESI JNS quaddiv2 INC EDI NEG EBX ADC ESI,0 NEG ESI quaddiv2: jnz quaddiv3 ;y >= 2^16? ;--------------------------------------- ;y < 2^16: or EBX,EBX jz quaddiv9 ;divide by zero? MOV ECX,EAX MOV EAX,EDX XOR EDX,EDX DIV EBX XCHG EAX,ECX DIV EBX JMP quaddiv6 ;--------------------------------------- ;y >= 2^16: quaddiv3: BSR ECX,ESI ;shift right x AND y so that y<2^16 INC CL PUSH EBX SHRD EBX,ESI,CL SHRD EAX,EDX,CL SHR EDX,CL DIV EBX ;estimate z MOV EBX,EAX ;multiply z with y MUL ESI MOV ECX,EAX POP EAX MUL EBX ADD EDX,ECX JC quaddiv4 ;compare z*y with x CMP EDX,(x).Big2 JA quaddiv4 JB quaddiv5 CMP EAX,(x).Big1 JBE quaddiv5 quaddiv4: DEC EBX ;decrement z if z*y > x quaddiv5: XOR ECX,ECX MOV EAX,EBX ;--------------------------------------- quaddiv6: DEC EDI jnz quaddiv7 NEG EAX ;change sign of result ADC ECX,0 NEG ECX quaddiv7: MOV EBX,z MOV [EBX].Big1,EAX MOV [EBX].Big2,ECX RET quaddiv9: ;divide error XOR EAX,EAX DEC EAX MOV ECX,7fffffffh JMP quaddiv6 ;return 7fffffffffffffffh QUADDIV endp ;----------------------------------------------------------------------------- ;void pascal quaddiva(Integer8* z, Integer8* x, Integer8* y) ;compute z=x*y public QUADDIVA QUADDIVA proc z:ptr, x:ptr, y:ptr PUSH z MOV EBX,x PUSH [EBX].Big2 PUSH [EBX].Big1 MOV EBX,y PUSH [EBX].Big2 PUSH [EBX].Big1 CALL QUADDIV RET QUADDIVA endp ;----------------------------------------------------------------------------- end mov eax, [esp+4] mov edx, [esp+8] add eax, [esp+12] adc edx, [esp+16] sub eax, [esp+12] sbb edx, [esp+16] Resultat auf EDX:EAX Eingabezeiger auf EBX oder ECX:EBX Zwischenspeichern flüchtig auf EDI:ESI Bei Zeiger Operationen für FPU solte der Wert direkt aus dem Speicher geholt werden ;----------------------------------------------------------------------------- ;void pascal quadinc(Var1:I8:A, Var2:I4) ;compute z=z+x QUADINC proc Var1:ptr, Var2:DWord MOV EAX, (Var1).Big1 ; [esp+4] MOV EDX, (Var1).Big2 ; [esp+8] ADD EAX, Var2 ; [esp+12] ADC EDX, 0 ;----------------------------------------------------------------------------- ;void pascal quadinc(Var1:I8:A, Var2:I8) ;compute z=z+x QUADINC proc Var1:ptr, Var2:qword MOV EAX, (Var1).Big1 ; [esp+4] MOV EDX, (Var1).Big2 ; [esp+8] MOV EBX, Var2 ADD EAX, [EBX].Big1 ; [esp+12] ADC EDX, [EBX].Big2 ; [esp+16] ;----------------------------------------------------------------------------- ;void pascal quadinca(Var1:I8:A, Var2:I8:A) ;compute z=z+x QUADINCA proc Var1:ptr, Var2:ptr MOV EBX, Var1 MOV EAX, [EBX].Big1 MOV EDX, [EBX].Big2 MOV EBX, Var2 ADD EAX, [EBX].Big1 ADC EDX, [EBX].Big2 pushfd and byte ptr [esp+0], 191 ;/* (type byte [esp]) */ or eax, [ebx+0] ;/* [ebx] */ setz al shl al, 6 or [esp+0], al ;/* [esp] */ popfd |