I écrit une fonction asm en Delphi 7, mais il transforme mon code à quelque chose d'autre:Étiquette Delphi et asm étrangeté?
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;
Pourquoi faut-il générer push ebx
et pop ebx
? Et pourquoi fait-il mov eax, ebx
? Il semble qu'il génère la trame de pile partielle en raison de mov eax, ebx
.
Ce test simple génère mov eax, edx
mais ne génère pas que cadre de pile:
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
Il semble qu'il a quelque chose à voir avec le label err
. Si j'enlève que je n'ai pas la pièce mov eax, *
.
Pourquoi cela se produit-il?
Fait un rapport de bogue sur Quality Central.
s'il vous plaît faire un rapport de bug à http://qc.embarcadero.com/wc/qcmain.aspx –
@Jeroen sûr. Aucun problème ... – Egon
Vous avez demandé plusieurs "pourquoi" ici, mais aucune d'entre elles n'a été répondue par la réponse que vous avez acceptée. Il semble que vous vouliez simplement savoir comment sauter à une nouvelle instruction dans l'assembleur Delphi sans tenir compte de la raison pour laquelle vos propres tentatives ont échoué. Est-ce exact? –