SAL和SAR由0错误组成

时间:2010-04-23 17:25:37

标签: assembly

我发现了一些我一直在使用的汇编代码中的错误,但无法弄清楚如何修复它。当向左移动0时,结果最终为0而不是突出数字。向右移动时同样适用。非常感谢任何和所有帮助。

function sal(n,k:integer):integer;
begin
 asm
 cld
 mov    cx,     k
@1:
  sal n, 1
  loop @1
 end;
 sal:= n;
end;

function sar(n,k:integer):integer;
begin
 asm
  cld
  mov   cx,     k
@1:
  sar   n,      1
  loop  @1
 end;
 sar:=n;
end;

我试图通过以下方式更改它们,但仍然无法正常工作。

function sal(n,k:integer):integer;
begin
 asm
 cld
 mov    cx,     k
 jcxz @done
@1:
  sal n, 1
  loop @1
@done:
 end;
 sal:= n;
end;

function sar(n,k:integer):integer;
begin
 asm
  cld
  mov   cx,     k
 jcxz @done
@1:
  sar   n,      1
  loop  @1
@done:
 end;
 sar:=n;
end;

4 个答案:

答案 0 :(得分:0)

答案 1 :(得分:0)

关于你的错误:如果k为零,那么循环将减少它并获得负值。循环检查仅为零。你的数字会减少,直到最终再次变为零。这会使你的数字大大改变,以至于所有比特都被移出。

答案 2 :(得分:0)

问题是mov指令没有设置任何标志。您可能希望在条件跳转之前添加test指令。

另外,我假设您在循环中执行此操作而不是使用单个指令?可以将计数粘在CL中。

答案 3 :(得分:0)

你有一个错字...... 使用 clc 代替 cld cld 指令将清除方向标志,clc将清除进位标志。

正确的asm代码......

asm
      mov    cx, k         //ecx for 32bit cpu mode
@1:
      clc 
      sal    n, 1
      loop   @1
end;

asm
      mov    cx, k         //ecx for 32bit cpu mode
@1: 
      shl    n, 1
      loop   @1
end;

asm
      mov    cl, k        
      shl    n, cl
end;

此代码在16位cpu模式下工作!

编辑: 为防止零位移,首先检查k = 0

 asm
      mov    cx, k         //ecx for 32bit cpu mode
      and    cl, cl        //zero test  
      jz     @Done
@1:
      clc
      sal    n, 1
      loop   @1
@Done:
 end;