* * *

Author Topic: DWORD bug ?  (Read 823 times)

comingnine

  • New member
  • *
  • Posts: 25
DWORD bug ?
« on: September 05, 2018, 10:36:44 am »
When cross compiled to linux-x86_64 on Windows 10, the code below produces "8BE6A858 18BE6A858 8B 18B 1 2" instead of "8BE6A858 8BE6A858 8B 8B 1 1". That is to say, temporary value of adding DWORD values is not DWORD. Could you help to comment whether this is a bug ?

Code: [Select]
{$IFDEF FPC}{$MODE DELPHI}{$ENDIF}
{$IFOPT D+} {$DEFINE DEBUG} {$ENDIF}
{$ASSERTIONS ON}
program DWordBug;
{$IFNDEF FPC}{$APPTYPE CONSOLE}{$ENDIF}
uses SysUtils;

var
  A, B, C: DWord;
  D: Byte;
  E: array [$00..$200] of Byte;
begin
  A := $BC48A8EC;
  B := $CF9DFF6C;
  C := A + B; 
  D := (A + B) shr 24;
  E[$8B] := 1;
  E[$18B] := 2;
  Writeln(Format('%x %x %x %x %x %x', [C, A+B, D, (A + B) shr 24, E[D], E[(A + B) shr 24]]));
end.
« Last Edit: September 05, 2018, 11:35:06 am by comingnine »

Thaddy

  • Hero Member
  • *****
  • Posts: 6923
Re: DWORD bug ?
« Reply #1 on: September 05, 2018, 10:45:37 am »
Which FPC version?
Ada's daddy wrote this:"Fools are my theme, let satire be my song."

comingnine

  • New member
  • *
  • Posts: 25
Re: DWORD bug ?
« Reply #2 on: September 05, 2018, 10:49:29 am »
Which FPC version?

Many thanks ! Is the info from fp.exe or fpc.exe enough ? I am not sure how to get the info from the linux cross-compiler but it probably should be the same ?

Code: [Select]
C:\fpcupdeluxe\fpc\bin\i386-win32>fp.exe
?Free Pascal IDE Version 1.0.12 [2018/07/28]

C:\fpcupdeluxe\fpc\bin\i386-win32>fpc.exe
Free Pascal Compiler version 3.1.1-r39514 [2018/07/28] for i386

C:\fpcupdeluxe\fpc\bin\i386-win32>ppcrossx64.exe
Free Pascal Compiler version 3.1.1-r39514 [2018/07/28] for x86_64


PS: Trunk FPC is installed with fpcupdeluxe.
« Last Edit: September 05, 2018, 10:57:07 am by comingnine »

Thaddy

  • Hero Member
  • *****
  • Posts: 6923
Re: DWORD bug ?
« Reply #3 on: September 05, 2018, 11:15:55 am »
Version is important to test. Behavior can differ. I will test against 39711
Ada's daddy wrote this:"Fools are my theme, let satire be my song."

WooBean

  • Jr. Member
  • **
  • Posts: 80
Re: DWORD bug ?
« Reply #4 on: September 05, 2018, 11:17:31 am »
...
 Could you help to comment whether this is a bug ?
...

Hi comingnine, 

calm down - FPC works OK.

When you arithmetically add A and B (DWORD type both) the proper result should be QWORD type. FPC "knows" it when is asked to produce text representation af A+B. Your C = (A+B) and $FFFFFFFF - as C has only 4 bytes.

WooBean
   
« Last Edit: September 05, 2018, 11:23:07 am by WooBean »
Win7/64, Lazarus 1.8 win64-win64, FPC 3.0.4

comingnine

  • New member
  • *
  • Posts: 25
Re: DWORD bug ?
« Reply #5 on: September 05, 2018, 11:20:21 am »
...
 Could you help to comment whether this is a bug ?
...

Hi comingnine, 

calm down - FPC works OK. 

So I have to declare an additional DWORD variable and assign the value before using the result ?
If the temporary/intermediate value is not DWORD, the shift operator on it simply does not work. Shift operator on temporary/intermediate values is very often seen, for example, in DCPcrypt. For example, DCPcrypt's DCPgost's SelfTest does not work because of this.
« Last Edit: September 05, 2018, 11:22:42 am by comingnine »

WooBean

  • Jr. Member
  • **
  • Posts: 80
Re: DWORD bug ?
« Reply #6 on: September 05, 2018, 11:36:31 am »
@comingnine

"So I have to declare an additional DWORD variable and assign the value before using the result ?"- No, safe type for adding two DWORD variables is QWORD (8 bytes long).

If you use expression result for some bit shifting operations you cannot assume that the size of that expression is the same as in used variables.
That is all.

WooBean

Win7/64, Lazarus 1.8 win64-win64, FPC 3.0.4

comingnine

  • New member
  • *
  • Posts: 25
Re: DWORD bug ?
« Reply #7 on: September 05, 2018, 11:48:22 am »
@comingnine

"So I have to declare an additional DWORD variable and assign the value before using the result ?"- No, safe type for adding two DWORD variables is QWORD (8 bytes long).

If you use expression result for some bit shifting operations you cannot assume that the size of that expression is the same as in used variables.
That is all.

WooBean

If what you say is correct (i.e., the expected behavior specified in the official documentation), one just has to either add a lot of hard-casts or to use several temporary variables and a lot of assignments to use existing codes such as DCPcrypt under x86_64.

comingnine

  • New member
  • *
  • Posts: 25
Re: DWORD bug ?
« Reply #8 on: September 05, 2018, 12:31:56 pm »
There is only one place different from the first post: the variables are declared to be Cardinal.

Code: [Select]
{$IFDEF FPC}{$MODE DELPHI}{$ENDIF}
{$IFOPT D+} {$DEFINE DEBUG} {$ENDIF}
{$ASSERTIONS ON}
program DWordBug;
{$IFNDEF FPC}{$APPTYPE CONSOLE}{$ENDIF}
uses SysUtils;

var
  A, B, C: Cardinal;
  D: Byte;
  E: array [$00..$200] of Byte;
begin
  A := $BC48A8EC;
  B := $CF9DFF6C;
  C := A + B;
  D := (A + B) shr 24;
  E[$8B] := 1;
  E[$18B] := 2;
  Writeln(Format('%x %x %x %x %x %x', [C, A+B, D, (A + B) shr 24, E[D], E[(A + B) shr 24]]));
  Readln;
end.

FPC linux-x86_64 and win-x86_64 gives "8BE6A858 18BE6A858 8B 18B 1 2".
Delphi win-x86_64 gives "8BE6A858 8BE6A858 8B 8B 1 1".

Nevertheless, I am not sure whether this is by design.

marcov

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 6544
Re: DWORD bug ?
« Reply #9 on: September 05, 2018, 12:47:24 pm »
If what you say is correct (i.e., the expected behavior specified in the official documentation), one just has to either add a lot of hard-casts or to use several temporary variables and a lot of assignments to use existing codes such as DCPcrypt under x86_64.

Only in places where a value >32-bit is an option, so assignment to 64-bit values, open array arguments (like format()) or variants.

And these aren't exactly common I guess, specially not in places where people expect overflows.

Your observations are mostly about the debug code, not the functional code itself.

comingnine

  • New member
  • *
  • Posts: 25
Re: DWORD bug ?
« Reply #10 on: September 05, 2018, 04:25:19 pm »
Your observations are mostly about the debug code, not the functional code itself.

For example, DCPcrypt's DCPgost's SelfTest does not work under linux x86_64 because of this behavior. In fact, addition of two numbers followed by bit shift of the (possibly truncated) result seems common in DCPcrypt.
« Last Edit: September 05, 2018, 04:30:19 pm by comingnine »

ASerge

  • Hero Member
  • *****
  • Posts: 945
Re: DWORD bug ?
« Reply #11 on: September 05, 2018, 10:29:42 pm »
More like a mistake in the documentation. In FPC there are no clear guidelines what type will have the value of A + B. In fact, it turns out, used Int64 for x64.
In Delphi, according to the documentation A + B remains of the same type as A and B (if they are the same).
By the way, this code is required {$RANGECHECKS OFF} - otherwise an error will occur. And if you enable optimization mode, the FPC will report at compile time: "Warning: range check error while evaluating constants (395 must be between 0 and 255)" on the line D := (A + B) shr 24; And in Delphi, given the fact that the result of the addition of 32 bit, also needed {$OVERFLOWCHECKS OFF}.

 

Recent

Get Lazarus at SourceForge.net. Fast, secure and Free Open Source software downloads Open Hub project report for Lazarus