gpt4 book ai didi

delphi - 为什么将此汇编代码移植到 x64 时会出现访问冲突?

转载 作者:行者123 更新时间:2023-12-03 15:50:24 25 4
gpt4 key购买 nike

我正在使用这个组件http://sourceforge.net/projects/tponguard/现在我需要在 64 位中编译。我被困在这个程序集中了。

事情是这样的:

  push esi
push edi

mov esi, eax //esi = Mem1
mov edi, edx //edi = Mem2

push ecx //save byte count
shr ecx, 2 //convert to dwords
jz @Continue

cld
@Loop1: //xor dwords at a time
mov eax, [edi]
xor [esi], eax
add esi, 4
add edi, 4
dec ecx
jnz @Loop1

@Continue: //handle remaining bytes (3 or less)
pop ecx
and ecx, 3
jz @Done

@Loop2: //xor remaining bytes
mov al, [edi]
xor [esi], al
inc esi
inc edi
dec ecx
jnz @Loop2

@Done:
pop edi
pop esi

我改成这样:

  push rsi
push rdi

mov rsi, rax //esi = Mem1
mov rdi, rdx //edi = Mem2

push rcx //save byte count
shr rcx, 2 //convert to dwords
jz @Continue

cld
@Loop1: //xor dwords at a time
mov rax, [rdi]
xor [rsi], rax
add rsi, 4
add rdi, 4
dec rcx
jnz @Loop1

@Continue: //handle remaining bytes (3 or less)
pop rcx
and rcx, 3
jz @Done

@Loop2: //xor remaining bytes
mov al, [rdi]
xor [rsi], al
inc rsi
inc rdi
dec rcx
jnz @Loop2

@Done:
pop rdi
pop rsi

但现在我在 xor [rsi]、rax 中遇到访问冲突

最佳答案

您正在查看的功能是

procedure XorMem(var Mem1; const Mem2; Count : Cardinal); register;

来自ogutil单元。

就我个人而言,我不会费心将其转换为 x64 汇编程序。为了做到这一点,您需要正确处理一些棘手的细节。对我来说,移植到 Pascal 并让编译器处理细节更有意义。最简单最幼稚的翻译如下:

procedure XorMem(var Mem1; const Mem2; Count: Cardinal);
var
p1, p2: PByte;
begin
p1 := PByte(@Mem1);
p2 := PByte(@Mem2);
while Count>0 do
begin
p1^ := p1^ xor p2^;
inc(p1);
inc(p2);
dec(Count);
end;
end;

如果这对性能至关重要,那么您需要稍微展开循环以对大操作数进行操作。比如说 x86 上的 32 位操作数和 x64 上的 64 位操作数。

在 32 位操作数上运行的版本可能如下所示:

procedure XorMem(var Mem1; const Mem2; Count: Cardinal);
var
p1, p2: PByte;
begin
p1 := PByte(@Mem1);
p2 := PByte(@Mem2);
while Count>3 do
begin
PCardinal(p1)^ := PCardinal(p1)^ xor PCardinal(p2)^;
inc(p1, 4);
inc(p2, 4);
dec(Count, 4);
end;
while Count>0 do
begin
p1^ := p1^ xor p2^;
inc(p1);
inc(p2);
dec(Count);
end;
end;

实际上,您可以轻松地编写一个根据编译目标自动使用 32 位或 64 位操作数的版本。诀窍是使用 NativeUInt 类型,即机器字大小。

procedure XorMem(var Mem1; const Mem2; Count: Cardinal);
var
p1, p2: PByte;
begin
p1 := PByte(@Mem1);
p2 := PByte(@Mem2);
while Count>SizeOf(NativeUInt)-1 do
begin
PNativeUInt(p1)^ := PNativeUInt(p1)^ xor PNativeUInt(p2)^;
inc(p1, SizeOf(NativeUInt));
inc(p2, SizeOf(NativeUInt));
dec(Count, SizeOf(NativeUInt));
end;
while Count>0 do
begin
p1^ := p1^ xor p2^;
inc(p1);
inc(p2);
dec(Count);
end;
end;

在启用优化的情况下编译时,这个最终版本非常高效。我不会超越最终的 Pascal 版本。

关于delphi - 为什么将此汇编代码移植到 x64 时会出现访问冲突?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17023838/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com