是否有Divmod *不*限于字词(< = 65535)? [英] Is there a DivMod that is *not* Limited to Words (<=65535)?
问题描述
在Delphi中,DivMod函数的声明是
程序DivMod(红利:红利主义;除数:Word;
var Result,Remainder:Word);
因此,除数,结果和余数不能超过65535,这是一个相当严重的限制。为什么是这样?为什么不能脱钩是
程序DivMod(红利:红衣主教;除数:红衣主教;
var结果,剩余:红衣主教);
该过程是使用程序集实现的,因此可能非常快。代码不可能
PUSH EBX
MOV EBX,EDX
MOV EDX,EAX
SHR EDX,16
DIV BX
MOV EBX,剩余
MOV [ECX],AX
MOV [EBX],DX
POP EBX
适应红衣主教?最初尝试的速度是多少?
procedure DivModInt(const Dividend:integer; const除数:integer; out result:integer; out余数:整数);
begin
result:=派息div除数;
余数:=股利除数;
结束
不是(?)限于16位整数?
这样的过程是可能的。我没有足够的测试代码,但我觉得没问题:
程序DivMod32(Dividend,Divisor:Cardinal; var Quotient,剩余:红衣主教);
asm
PUSH EBX
MOV EBX,EDX
XOR EDX,EDX
DIV EBX
MOV [ECX],EAX
MOV EBX,剩余
MOV [EBX],EDX
POP EBX
结束;
更新: / p>
更高效:
功能DivMod32(股息,除数:红衣主教; var Remainder:Cardinal):红衣主教;
asm
PUSH EBX
MOV EBX,EDX
XOR EDX,EDX
DIV EBX
MOV [ECX],EDX
POP EBX
结束;
更新2:
您可以在反汇编(或CPU)窗口中查看由Delphi编译器生成的汇编代码。例如,程序
程序DivMod32(const Dividend:Cardinal; const Divisor:Cardinal;
输出结果:Cardinal;剩余部分:红衣主教);
begin
result:=派息div除数;
余数:=股利除数;
结束
生成代码
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:余数:=股息mod除数;
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
此代码是线性的(不包含跳转)和现代处理器(具有长指令流水线)在执行线性代码方面非常有效。所以尽管我的DivMode32实现时间缩短了约三倍,但是60%是一个合理的估计。
In Delphi, the declaration of the DivMod function is
procedure DivMod(Dividend: Cardinal; Divisor: Word;
var Result, Remainder: Word);
Thus, the divisor, result, and remainder cannot be grater than 65535, a rather severe limitation. Why is this? Why couldn't the delcaration be
procedure DivMod(Dividend: Cardinal; Divisor: Cardinal;
var Result, Remainder: Cardinal);
The procedure is implemented using assembly, and is therefore probably extremely fast. Would it not be possible for the code
PUSH EBX
MOV EBX,EDX
MOV EDX,EAX
SHR EDX,16
DIV BX
MOV EBX,Remainder
MOV [ECX],AX
MOV [EBX],DX
POP EBX
to be adapted to cardinals? How much slower is the naïve attempt
procedure DivModInt(const Dividend: integer; const Divisor: integer; out result: integer; out remainder: integer);
begin
result := Dividend div Divisor;
remainder := Dividend mod Divisor;
end;
that is not (?) limited to 16-bit integers?
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.
这篇关于是否有Divmod *不*限于字词(< = 65535)?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!