Is it possible that this code in Delphi XE is defect? I keep getting AVs in the last line:
Is it possible that this code in Delphi XE is defect? I keep getting AVs in the last line:
class function TInterlocked.CompareExchange(var Target: Integer; Value: Integer; Comparand: Integer; out Succeeded: Boolean): Integer;
asm
XCHG EAX,EDX
XCHG EAX,ECX
LOCK CMPXCHG [EDX],ECX
MOV ECX,[ESP+4]
SETZ [ECX].Boolean
end;
class function TInterlocked.CompareExchange(var Target: Integer; Value: Integer; Comparand: Integer; out Succeeded: Boolean): Integer;
asm
XCHG EAX,EDX
XCHG EAX,ECX
LOCK CMPXCHG [EDX],ECX
MOV ECX,[ESP+4]
SETZ [ECX].Boolean
end;
/sub
ReplyDeleteThe `Succeded` parameter is not in [ESP+4] because the compiler creates stack frame for the function.
ReplyDeleteDebugging shows that the parameter is passed in [EBP+8], but you need not calculate offsets manually and simply write
MOV ECX,Succeeded.
Sergey Kasandrov Thanks, that code is from the Delphi XE RTL (SyncObjs.pas) and not written by me though. Later versions are using the AtomicCmpExchange intrinsic which obviously works.
ReplyDeleteYep, found it now; it is RTL bug.
ReplyDeleteSame thing in XE2 - but there is an interesting .NOFRAME pragma...
ReplyDeleteclass function TInterlocked.CompareExchange(var Target: Integer; Value: Integer; Comparand: Integer; out Succeeded: Boolean): Integer;
{$IFDEF X64ASM}
asm
.NOFRAME
MOV EAX,R8d
LOCK CMPXCHG [RCX].Integer,EDX
SETZ [R9].Boolean
end;
{$ELSE !X64ASM}
{$IFDEF X86ASM}
asm
XCHG EAX,EDX
XCHG EAX,ECX
LOCK CMPXCHG [EDX],ECX
MOV ECX,[ESP+4]
SETZ [ECX].Boolean
end;
{$ENDIF X86ASM}
{$ENDIF !X64ASM}
and none of those functions uses source\rtl\sys\InterlockedAPIs.inc - Delphi RTL team seems chaotic or disconnected, reinventing the wheel time and again...
That's because [ESP+4] does not reference to Succeeded param. It's better to enable stackframes that allows you to access stack without making many changes to your asm code.
ReplyDeleteThis will do the trick:
----------------------------
MOV ECX,[EBP+8] // Skip stackframe + return address.