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关键字. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |