Delphi label and asm weirdness?

Posted by egon on Stack Overflow See other posts from Stack Overflow or by egon
Published on 2010-03-07T09:20:20Z Indexed on 2010/04/01 0:23 UTC
Read the original article Hit count: 872

Filed under:
|
|
|

I written an asm function in Delphi 7 but it transforms my code to something else:

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;

Why does it generate push ebx and pop ebx? And why does it do mov eax, ebx?

It seems that it generates the partial stack frame because of the mov eax, ebx.

This simple test generates mov eax, edx but doesn't generate that stack frame:

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

It seems that it has something to do with the label err. If I remove that I don't get the mov eax, * part.

Why does this happen?


Made a bug report on Quality Central.

© Stack Overflow or respective owner

Related posts about delphi

Related posts about delphi-7