|
@@ -0,0 +1,129 @@
|
|
|
+{ %cpu=i386 }
|
|
|
+
|
|
|
+program asm_bug;
|
|
|
+{$IFDEF FPC}
|
|
|
+{$mode delphi}
|
|
|
+{$OPTIMIZATION SIZE}
|
|
|
+{$OPTIMIZATION STACKFRAME}
|
|
|
+{$OPTIMIZATION REGVAR}
|
|
|
+{$CODEALIGN VARMIN=1}
|
|
|
+{$CODEALIGN VARMAX=1}
|
|
|
+{$CODEALIGN CONSTMIN=1}
|
|
|
+{$CODEALIGN CONSTMAX=1}
|
|
|
+{$ENDIF}
|
|
|
+
|
|
|
+{$ALIGN 1}
|
|
|
+{$APPTYPE CONSOLE}
|
|
|
+
|
|
|
+{$IFDEF XXX}
|
|
|
+ o study of explicit/impicit operand size def
|
|
|
+{$ENDIF}
|
|
|
+
|
|
|
+type
|
|
|
+
|
|
|
+obj1t = object //__ fpc.exe eat "packed object" delphi 2007 does not eat _
|
|
|
+b0 :byte;
|
|
|
+b1 :byte;
|
|
|
+b2 :byte;
|
|
|
+b3 :byte;
|
|
|
+procedure proc0(); register;
|
|
|
+procedure proc1(); register;
|
|
|
+procedure proc2(); register;
|
|
|
+procedure proc3(); register;
|
|
|
+procedure pascal(); register;
|
|
|
+end;
|
|
|
+
|
|
|
+var
|
|
|
+
|
|
|
+obj1 :obj1t;
|
|
|
+error: boolean;
|
|
|
+
|
|
|
+
|
|
|
+procedure obj1t.proc0(); //___ it is seems to good but the last mov scrabble 3 byte after obj1 (with fpc.exe) _
|
|
|
+ASM //___________ proc1 __
|
|
|
+ mov [eax].b0 , 0 //___ affable pascal like syntax but the "byte ptr" info not present (with DCC32(delphi) present)
|
|
|
+ mov [eax].b1 , 1
|
|
|
+ mov [eax].b2 , 2
|
|
|
+ mov [eax].b3 , 3
|
|
|
+end; //___________ proc1 __
|
|
|
+
|
|
|
+procedure obj1t.proc1();
|
|
|
+ASM //___________ proc1 __
|
|
|
+ mov [eax].b3 , 3 //___ reverse order to detect scrabbling _
|
|
|
+ mov [eax].b2 , 2
|
|
|
+ mov [eax].b1 , 1
|
|
|
+ mov [eax].b0 , 0 //____ clear all four byte value with fpc __
|
|
|
+end; //___________ proc1 __
|
|
|
+
|
|
|
+procedure obj1t.proc2();
|
|
|
+ASM //___________ proc1 __
|
|
|
+ mov [eax.b3] , 3 //___ this syntax preferable maybe _
|
|
|
+ mov [eax.b2] , 2
|
|
|
+ mov [eax.b1] , 1
|
|
|
+ mov [eax.b0] , 0
|
|
|
+end; //___________ proc1 __
|
|
|
+
|
|
|
+procedure obj1t.proc3(); //___ naturally this proc work well _
|
|
|
+ASM //___________ proc1 __
|
|
|
+ mov byte ptr [eax.b3] , 3 //___ _
|
|
|
+ mov byte ptr [eax.b2] , 2
|
|
|
+ mov byte ptr [eax.b1] , 1
|
|
|
+ mov byte ptr [eax.b0] , 0
|
|
|
+end; //___________ proc1 __
|
|
|
+
|
|
|
+
|
|
|
+procedure obj1t.pascal();
|
|
|
+begin //___________ pascal __
|
|
|
+ b3:= 3;
|
|
|
+ b2:= 2;
|
|
|
+ b1:= 1;
|
|
|
+ b0:= 0;
|
|
|
+end; //___________ pascal __
|
|
|
+
|
|
|
+type
|
|
|
+str31 = string[31];
|
|
|
+procedure wr_obj(e :str31);
|
|
|
+begin //___________ wr_obj __
|
|
|
+ with obj1 do writeln(b0:3,b1:3,b2:3,b3:3, ' must be:[0 1 2 3] ',e); //___
|
|
|
+ if (obj1.b0<>0) or
|
|
|
+ (obj1.b1<>1) or
|
|
|
+ (obj1.b2<>2) or
|
|
|
+ (obj1.b3<>3) then
|
|
|
+ error:=true;
|
|
|
+end; //___________ wr_obj __
|
|
|
+
|
|
|
+var
|
|
|
+a1,a2 :ptruint;
|
|
|
+
|
|
|
+var
|
|
|
+c0,c1,c2,c3 :byte; //___ the test with internal assemlber not fair because of 16-byte aligment of global variables _
|
|
|
+
|
|
|
+begin //____ m a i n _
|
|
|
+ a1:= ptruint(@obj1.b0);
|
|
|
+ a2:= ptruint(@obj1.b1);
|
|
|
+ if ((a2-a1) <> 1) then begin writeln('obj1 not packed:'); halt(1); end;
|
|
|
+
|
|
|
+ obj1.proc0(); wr_obj('fwd');
|
|
|
+ obj1.proc1(); wr_obj('bwd');
|
|
|
+ obj1.proc2(); wr_obj('bwd');
|
|
|
+ obj1.proc3(); wr_obj('byte ptr');
|
|
|
+ obj1.pascal(); wr_obj('pascal');
|
|
|
+
|
|
|
+ASM
|
|
|
+ lea eax , c1
|
|
|
+ sub eax , offset c0
|
|
|
+ mov a1 , eax
|
|
|
+ mov [c3] , 3 //___ there is "byte ptr" info present _
|
|
|
+ mov [c2] , 2
|
|
|
+ mov [c1] , 1
|
|
|
+ mov [c0] , 0
|
|
|
+end;
|
|
|
+ writeln(c0:3,c1:3,c2:3,c3:3, ' must be:[0 1 2 3] glo'); //___
|
|
|
+ if (c0<>0) or
|
|
|
+ (c1<>1) or
|
|
|
+ (c2<>2) or
|
|
|
+ (c3<>3) then
|
|
|
+ error:=true;
|
|
|
+ if error then
|
|
|
+ halt(1);
|
|
|
+end.
|