![]() |
Division großer Zahlen in Assembler - Hilfe beim Verständnis
Hi :hi:
Kann man mir bitte mal Teile des nachfolgenden Assembler-Code (auch gerne den Ganzen) aus der System.pas erklären ? Es ist ja soweit ersichtlich, dass dort eine Division zweier 64-Bit-Integer durchgeführt wird, aber ich verstehe den Sinn einiger Befehlsfolgen nicht. Ich habe zwar eine komplette Referenz aller (Intel-)Assembler-Befehle mit Erklärungen, an deren Verständnis es nicht hakt, aber Ich bin kein Assembler-Profi und kein Mathematik-Spezi. :angel2: Die Prozedur "__lldiv" ist ja eine Software-Umsetzung für Divisionen von 64-Bit-Integern auf 32-Bit-CPUs. Demnach müsste sie sich ja auf größere Zahlen erweitern lassen. Natürlich müssten die Zahlen dann in einem Array gespeichert werden (imho), z.B. einem array [0..3] of DWORD für 128-Bit-Zahlen. Also bei mir hapert es jetzt an drei Stellen: 1. am Verständnis einiger Assembler-Befehle 2. am Verständnis einiger Assembler-Befehlsfolgen 3. an der Erweiterung auf größere Zahlen in Array-Form Ich suche also nach einer allgemeinen Erklärung des Ablaufs dieser Prozedur, und, wenn dann noch nötig, nach Hilfe für eine Erweiterung. Ich suche NICHT nach einer Bibliothek, die mir das Lernen abnimmt. Ich hoffe, man kann mir weiterhelfen: 1.: Was sagt mit diese Zeile:
Delphi-Quellcode:
Ich kenne nur solche Befehle:
mov ebx,20[esp]
Delphi-Quellcode:
2:
mov ebp,ecx
mov ecx,64 Warum werden hier die Register edx, esi und edi um 1 über das Carry hinweg rotiert:
Delphi-Quellcode:
Das waren wahrscheinlich nur die ersten Fragen...
@__lldiv@xloop:
shl eax,1 rcl edx,1 rcl esi,1 rcl edi,1
Delphi-Quellcode:
// ------------------------------------------------------------------------------
// 64-bit signed division // ------------------------------------------------------------------------------ // // Dividend = Numerator, Divisor = Denominator // // Dividend(EAX:EDX), Divisor([ESP+8]:[ESP+4]) ; before reg pushing // // procedure __lldiv; asm push ebp push ebx push esi push edi xor edi,edi mov ebx,20[esp] // get the divisor low dword mov ecx,24[esp] // get the divisor high dword or ecx,ecx jnz @__lldiv@slow_ldiv // both high words are zero or edx,edx jz @__lldiv@quick_ldiv or ebx,ebx jz @__lldiv@quick_ldiv // if ecx:ebx == 0 force a zero divide // we don't expect this to actually // work @__lldiv@slow_ldiv: // Signed division should be done. Convert negative // values to positive and do an unsigned division. // Store the sign value in the next higher bit of // di (test mask of 4). Thus when we are done, testing // that bit will determine the sign of the result. or edx,edx // test sign of dividend jns @__lldiv@onepos neg edx neg eax sbb edx,0 // negate dividend or edi,1 @__lldiv@onepos: or ecx,ecx // test sign of divisor jns @__lldiv@positive neg ecx neg ebx sbb ecx,0 // negate divisor xor edi,1 @__lldiv@positive: mov ebp,ecx mov ecx,64 // shift counter push edi // save the flags // // Now the stack looks something like this: // // 24[esp]: divisor (high dword) // 20[esp]: divisor (low dword) // 16[esp]: return EIP // 12[esp]: previous EBP // 8[esp]: previous EBX // 4[esp]: previous ESI // [esp]: previous EDI // xor edi,edi // fake a 64 bit dividend xor esi,esi @__lldiv@xloop: shl eax,1 // shift dividend left one bit rcl edx,1 rcl esi,1 rcl edi,1 cmp edi,ebp // dividend larger? jb @__lldiv@nosub ja @__lldiv@subtract cmp esi,ebx // maybe jb @__lldiv@nosub @__lldiv@subtract: sub esi,ebx sbb edi,ebp // subtract the divisor inc eax // build quotient @__lldiv@nosub: loop @__lldiv@xloop // // When done with the loop the four registers values' look like: // // | edi | esi | edx | eax | // | remainder | quotient | // pop ebx // get control bits test ebx,1 // needs negative jz @__lldiv@finish neg edx neg eax sbb edx,0 // negate @__lldiv@finish: pop edi pop esi pop ebx pop ebp ret 8 @__lldiv@quick_ldiv: div ebx // unsigned divide xor edx,edx jmp @__lldiv@finish end; |
Alle Zeitangaben in WEZ +1. Es ist jetzt 21:40 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz