将 Delphi 风格的 ASM 翻译成英文?

发布于 2024-12-12 06:55:39 字数 1339 浏览 4 评论 0原文

我最近继承的一个Delphi项目有一个ASM过程。我是一个完全的ASM新手,所以我不明白它。我已经阅读了各种 ASM 指令来尝试破译程序流程,但我仍然不明白。

有 ASM 经验的人可以帮助我理解并将以下过程翻译成英文(然后我可以翻译回 Delphi,以便将来代码更容易阅读!!!)

Mem1 的声明是一个数组 [0. .15]字节;Mem2 是一个 LongInt

程序如下:

 procedure TForm1.XorMem(var Mem1; const Mem2; Count : Cardinal); register;
 begin
 asm
   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
 end;

 end;

编辑:感谢 Roman R,我已将 ASM 转换回 Delphi

procedure TForm1.XorMem2(var Mem1; const Mem2 :LongInt; Count : Cardinal);
var
  Key : array [0..3] of byte absolute Mem1;
  Num : array [0..3] of byte absolute Mem2;
  idx : byte;
begin
  for Idx := 0 to Count -1 do Key[idx] := Key[idx] Xor Num[idx];
end;

A recent Delphi project i've inherited has a procedure in ASM. I'm a complete ASM newbie, so i dont understand it. I've read up on the various ASM instructions to try and decipher the procedures flow, but i still dont get it.

Could someone with ASM experience assist my understanding and translate the following procedure to English (then i can translate back to Delphi so the code is easier to read in the future!!!)

The declaration of Mem1 is an array [0..15] of Byte;. And Mem2 is a LongInt.

Here's the procedure:

 procedure TForm1.XorMem(var Mem1; const Mem2; Count : Cardinal); register;
 begin
 asm
   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
 end;

 end;

edit: Thanks to Roman R i've converted the ASM back to Delphi

procedure TForm1.XorMem2(var Mem1; const Mem2 :LongInt; Count : Cardinal);
var
  Key : array [0..3] of byte absolute Mem1;
  Num : array [0..3] of byte absolute Mem2;
  idx : byte;
begin
  for Idx := 0 to Count -1 do Key[idx] := Key[idx] Xor Num[idx];
end;

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

半山落雨半山空 2024-12-19 06:55:39

该函数接受两个指针(指向任何数组)及其长度(以字节为单位)。该函数使用第二个数组字节 (Mem2) 对第一个数组字节 (Mem1) 执行字节到字节 XOR 运算。伪代码:

for Index = 0 to Count - 1
  (Mem1 as Byte Array) [Index] = (Mem1 as Byte Array) [Index] Xor (Mem2 as Byte Array) [Index]

The function accepts two pointers (to arrays whatever) and their lengths in bytes. The function performs byte-to-byte XOR operation on first array bytes (Mem1) using second array bytes (Mem2). Pseudo-code:

for Index = 0 to Count - 1
  (Mem1 as Byte Array) [Index] = (Mem1 as Byte Array) [Index] Xor (Mem2 as Byte Array) [Index]
白芷 2024-12-19 06:55:39

这是一个有效且简单的纯 pascal 版本:

procedure TForm1.XorMem(var Mem1; const Mem2; Count : Cardinal);
var i: integer;
    M1: TByteArray absolute Mem1;
    M2: TByteArray absolute Mem2;
begin
  for i := 0 to Count-1 do
     M1[i] := M1[i] xor M2[i];
end;

这是一个使用 DWORD 读取的优化版本:

procedure TForm1.XorMem(var Mem1; const Mem2; Count : Cardinal);
var i, n: integer;
    M1: TByteArray absolute Mem1;
    M2: TByteArray absolute Mem2;
    I1: TIntegerArray absolute Mem1;
    I2: TIntegerArray absolute Mem2;
begin
  n := Count shr 2;
  for i := 0 to n-1 do
     I1[i] := I1[i] xor I2[i];
  n := n shl 2;
  for i := 0 to (Count and 3)-1 do
     M1[n+i] := M1[n+i] xor M2[n+i];
end;

恕我直言,第二个版本不是强制性的。如果数据是 DWORD 对齐的,则一次读取 DWORD 是有意义的。否则,它实际上会变慢。对于少量数据,一个小的 Delphi 循环将足够快,并且易于阅读。最新的 CPU(如 Core i5 或 i7)在使用小型代码循环时会创造奇迹(不再需要展开循环)。

Here is a working and simple pure pascal version:

procedure TForm1.XorMem(var Mem1; const Mem2; Count : Cardinal);
var i: integer;
    M1: TByteArray absolute Mem1;
    M2: TByteArray absolute Mem2;
begin
  for i := 0 to Count-1 do
     M1[i] := M1[i] xor M2[i];
end;

Here is an optimized version using DWORD reading:

procedure TForm1.XorMem(var Mem1; const Mem2; Count : Cardinal);
var i, n: integer;
    M1: TByteArray absolute Mem1;
    M2: TByteArray absolute Mem2;
    I1: TIntegerArray absolute Mem1;
    I2: TIntegerArray absolute Mem2;
begin
  n := Count shr 2;
  for i := 0 to n-1 do
     I1[i] := I1[i] xor I2[i];
  n := n shl 2;
  for i := 0 to (Count and 3)-1 do
     M1[n+i] := M1[n+i] xor M2[n+i];
end;

IMHO the 2nd version is not mandatory. Reading a DWORD at once makes sense if data is DWORD aligned. Otherwise, it can be effectively slower. For small amount of data, a small Delphi loop will be fast enough, and clear to read. Latest CPUs (like Core i5 or i7) make wonders when using a small code loop (unrolling a loop is not necessary any more).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文