我发现了一些我一直在使用的汇编代码中的错误,但无法弄清楚如何修复它。当向左移动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;
答案 0 :(得分:0)
shr
和shl
怎么办? http://www.delphibasics.co.uk/RTL.asp?Name=Shr http://www.delphibasics.co.uk/RTL.asp?Name=Shl
答案 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;