Is there a DivMod that is *not* Limited to Words (<=65535)?

后端 未结 1 1046
Happy的楠姐
Happy的楠姐 2021-01-01 03:59

In Delphi, the declaration of the DivMod function is

procedure DivMod(Dividend: Cardinal; Divisor: Word;
  var Result, Remainder: Word);

Th

1条回答
  •  迷失自我
    2021-01-01 04:14

    Such a procedure is possible. I have not tested the code enough, but I think it's OK:

    procedure DivMod32(Dividend, Divisor: Cardinal; var Quotient, Remainder: Cardinal);
    asm
            PUSH EBX
            MOV  EBX,EDX
            XOR  EDX,EDX
            DIV  EBX
            MOV  [ECX],EAX
            MOV  EBX,Remainder
            MOV  [EBX],EDX
            POP  EBX
    end;
    

    Updated:

    even more efficient:

    function DivMod32(Dividend, Divisor: Cardinal; var Remainder: Cardinal): Cardinal;
    asm
            PUSH EBX
            MOV  EBX,EDX
            XOR  EDX,EDX
            DIV  EBX
            MOV  [ECX],EDX
            POP  EBX
    end;
    

    Updated 2:

    You can see the assembly code generated by Delphi compiler in the Disassembly (or CPU) window. Eg, the procedure

    procedure DivMod32(const Dividend: Cardinal; const Divisor: Cardinal;
                        out result: Cardinal; out remainder: Cardinal);
    begin
      result := Dividend div Divisor;
      remainder := Dividend mod Divisor;
    end;
    

    generates code

    Unit1.pas.28: begin
    0046CC94 55               push ebp
    0046CC95 8BEC             mov ebp,esp
    0046CC97 53               push ebx
    0046CC98 56               push esi
    0046CC99 8BF2             mov esi,edx
    0046CC9B 8BD8             mov ebx,eax
    Unit1.pas.29: result := Dividend div Divisor;
    0046CC9D 8BC3             mov eax,ebx
    0046CC9F 33D2             xor edx,edx
    0046CCA1 F7F6             div esi
    0046CCA3 8901             mov [ecx],eax
    Unit1.pas.30: remainder := Dividend mod Divisor;
    0046CCA5 8BC3             mov eax,ebx
    0046CCA7 33D2             xor edx,edx
    0046CCA9 F7F6             div esi
    0046CCAB 8B4508           mov eax,[ebp+$08]
    0046CCAE 8910             mov [eax],edx
    Unit1.pas.31: end;
    0046CCB0 5E               pop esi
    0046CCB1 5B               pop ebx
    0046CCB2 5D               pop ebp
    0046CCB3 C20400           ret $0004
    

    This code is linear (contains no jumps) and modern processors (with long instruction pipeline) are very efficient in executing linear code. So though my DivMode32 implementation is about 3 times shorter, 60% is a reasonable estimate.

    0 讨论(0)
提交回复
热议问题