加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

Delphi标签和asm怪异?

发布时间:2020-12-15 09:33:09 所属栏目:大数据 来源:网络整理
导读:我在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 r
我在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
  jz  +$0e
  mov 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 ebx和pop ebx?为什么它会运行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,edx  // !!!
  ret

它似乎与标签错误有关.如果我删除了我没有获得mov eax,* part.

为什么会这样?

在Quality Central上做了一个错误报告.

解决方法

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

function f(x: Cardinal): Cardinal; register;
asm
  not eax
  mov edx,eax
  jz  @@err
  mov eax,edx
  ret
@@err:
  xor eax,eax
end;

更新:

我没有在Basm area中找到错误报告.它看起来像一个错误,但我已经使用BASM多年了,从来没有想过使用标签关键字这样的方式.实际上我从来没有在Delphi中使用label关键字.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读