gpt4 book ai didi

Delphi标签和asm怪异?

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

我在 Delphi 7 中编写了一个 asm 函数,但它将我的代码转换为其他代码:

function f(x: Cardinal): Cardinal; register;
label err;
asm
not eax
mov edx,eax
shr edx, 1
and eax, edx
bsf ecx, eax
jz err
mov eax, 1
shl eax, cl
mov edx, eax
add edx, edx
or eax, edx
ret
err:
xor eax, eax
end;

// compiled version
f:
push ebx // !!!
not eax
mov edx,eax
shr edx, 1
and eax, edx
bsf ecx, eax
jz +$0e
mov eax, 1
shl eax, cl
mov edx, eax
add edx, edx
or eax, edx
ret
err:
xor eax, eax
mov eax, ebx // !!!
pop ebx // !!!
ret

// the almost equivalent without asm
function f(x: Cardinal): Cardinal;
var
c: Cardinal;
begin
x := not x;
x := x and x shr 1;
if x <> 0 then
begin
c := bsf(x); // bitscanforward
x := 1 shl c;
Result := x or (x shl 1)
end
else
Result := 0;
end;

为什么它会生成push ebxpop ebx?为什么它会执行mov eax, ebx

似乎是由于 mov eax, ebx 生成了部分堆栈帧。

这个简单的测试生成 mov eax, edx 但不生成该堆栈帧:

function asmtest(x: Cardinal): Cardinal; register;
label err;
asm
not eax
and eax, 1
jz err
ret
err:
xor eax, eax
end;

// compiled
asmtest:
not eax
and eax, $01
jz +$01
ret
xor eax, eax
mov eax, edx // !!!
ret

看来与label err有关。如果我删除它,我就不会得到 mov eax, * 部分。

为什么会发生这种情况?

<小时/>

Quality Central 进行了错误报告.

最佳答案

实用的建议是:不要在asm代码中使用label关键字,使用@@前缀的标签:

function f(x: Cardinal): Cardinal; register;
asm
not eax
mov edx,eax
shr edx, 1
and eax, edx
bsf ecx, eax
jz @@err
mov eax, 1
shl eax, cl
mov edx, eax
add edx, edx
or eax, edx
ret
@@err:
xor eax, eax
end;
<小时/>

更新:

我在 Basm area 中没有找到错误报告。它看起来像一个bug,但我已经使用BASM很多年了,从来没有想过以这种方式使用标签关键字。事实上我从来没有在 Delphi 中使用过 label 关键字。 :)

关于Delphi标签和asm怪异?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2395735/

25 4 0