www.digitalmars.com         C & C++   DMDScript  

c++ - Wierd behaviour with mixed ASM and C++

reply "KarL" <someone somewhere.org> writes:
Content-Type: text/plain;
	charset="iso-8859-1"
Content-Transfer-Encoding: quoted-printable

Source:
class someobj {    unsigned char m_cC;public:    void =
somebuggyfunction();    void somefunction();}
somepublicfunction(){    __asm   mov dx, 0x300    __asm   mov al, m_cC   =
 __asm   out dx,al}
void someobj::somebuggyfunction(){    __asm   mov dx, 0x300    __asm   =
mov al, m_cC    __asm   out dx,al}
void someobj::somefunction(){    m_cC =3D 0x56;}
Obj2ASM output:
_TEXT   segment dword use32 public 'CODE'       ;size is 28_TEXT   =
ends_DATA   segment dword use32 public 'DATA'       ;size is 0_DATA   =
endsCONST   segment dword use32 public 'CONST'      ;size is 0CONST   =
ends_BSS    segment dword use32 public 'BSS'        ;size is 0_BSS    =
endsFLAT    groupincludelib SNN.lib

        public  ?somepublicfunction  YA?AVsomeobj  XZ        public  =
?somebuggyfunction someobj  QAEXXZ        public  =
?somefunction someobj  QAEXXZ_TEXT   segment        assume  =
CS:_TEXT?somepublicfunction  YA?AVsomeobj  XZ:                mov     =
DX,0300h                mov     AL,0                out     DX,AL        =
        ret?somebuggyfunction someobj  QAEXXZ:                enter   =
4,0                mov     -4[EBP],ECX                mov     DX,0300h   =
             mov     AL,0                out     DX,AL                =
leave                ret?somefunction someobj  QAEXXZ:                =
mov     byte ptr [ECX],056h                ret_TEXT   ends_DATA   =
segment_DATA   endsCONST   segmentCONST   ends_BSS    segment_BSS    =
ends        end
My Comments:
The "somepublicfunction" did not report the error on using m_cC in the =
inline assembly - since
m_cC is not declared as a global variable.

The same thing with someobj::somepublicfunction which failed to generate =
the someobj::m_cC
reference.

someobj::somefunction appears to be OK.
Aug 06 2002
next sibling parent reply Roland <rv ronetech.com> writes:
Content-Type: text/plain; charset=iso-8859-1
Content-Transfer-Encoding: 8bit



KarL a écrit :

 Source:
 .
 .

 somepublicfunction()
 {
     __asm   mov dx, 0x300
     __asm   mov al, m_cC
     __asm   out dx,al
 }

you are loading the offset of m_cC in al ! you have to do like this: asm mov eax,this asm mov al,[eax].m_cC roland
Aug 07 2002
parent reply "KarL" <someone somewhere.org> writes:
Content-Type: text/plain;
	charset="iso-8859-1"
Content-Transfer-Encoding: quoted-printable

  Roland <rv ronetech.com> wrote in message =
news:3D50F00A.EBF0567 ronetech.com...
   =20
  KarL a =E9crit :=20

    Source:=20
    .=20
    .=20
somepublicfunction()
{
    __asm   mov dx, 0x300
    __asm   mov al, m_cC
    __asm   out dx,al
}

  you are loading the offset of m_cC in al !=20
  you have to do like this:=20

  asm    mov  eax,this=20
  asm    mov  al,[eax].m_cC=20

  roland=20

NO. It shouldn't even compile at all!

somepublicfunction() is a global function and is unable to even see =
m_cC!

Borland's compilers both returns the following messages:
C:\tmp\bugtest>bcc32 -S bug.cppBorland C++ 5.0 for Win32 Copyright (c) =
1993, 1996 Borland Internationalbug.cpp:Error bug.cpp 9: Type 'someobj' =
may not be defined hereWarning bug.cpp 13: Function should return a =
value in function somepublicfunction()Error bug.cpp 18: Expression =
syntax in function someobj::somebuggyfunction()*** 2 errors in Compile =
***
C:\tmp\bugtest>bcc -S bug.cppBorland C++ 5.0 Copyright (c) 1987, 1996 =
Borland Internationalbug.cpp:Error bug.cpp 9: Type 'someobj' may not be =
defined hereWarning bug.cpp 13: Function should return a value in =
function somepublicfunction()Error bug.cpp 18: Expression syntax in =
function someobj::somebuggyfunction()*** 2 errors in Compile ***
What was missed in the defination of the class someobj is at the end of =
the class
defination, there was NO ';' at the end of the '}' after the defination =
of someobj.

What I change it to this:
class someobj {    unsigned char m_cC;    // This is private to someobj =
onlypublic:    void somebuggyfunction();    void somefunction();}; // =
NOTICE THE ';' now...
somepublicfunction()    // This is a global function{    __asm   mov dx, =
0x300    __asm   mov al, m_cC    // trying to access non global variable =
   __asm   out dx,al}
void someobj::somebuggyfunction(){    __asm   mov dx, 0x300    __asm   =
mov al, m_cC    // Question, 16-bit and 32-bit compatible???    __asm   =
out dx,al}
void someobj::somefunction(){    m_cC =3D 0x56;}
Borland compilers now says:
C:\tmp\bugtest>bcc -S bug.cppBorland C++ 5.0 Copyright (c) 1987, 1996 =
Borland Internationalbug.cpp:Warning bug.cpp 13: Function should return =
a value in function somepublicfunction()Error bug.cpp 18: Expression =
syntax in function someobj::somebuggyfunction()*** 1 errors in Compile =
***
C:\tmp\bugtest>bcc32 -S bug.cppBorland C++ 5.0 for Win32 Copyright (c) =
1993, 1996 Borland Internationalbug.cpp:Warning bug.cpp 13: Function =
should return a value in function somepublicfunction()Error bug.cpp 18: =
Expression syntax in function someobj::somebuggyfunction()*** 1 errors =
in Compile ***
It now correctly informed me that I can't use that expression for =
accessing the class member m_cC but
also failed to tell me that someglobalfunction cannot see m_cC.

If I change the someglobalfunction()'s accessing of m_cC into something =
else, DM will tell me this:
C:\tmp\bugtest>sc -C bug.cpp        __asm   mov     al, =
ThisIsABogusVariable                                               =
^bug.cpp(11) : Warning 13: Illegal type/size of operands for the mov =
instruction}^bug.cpp(13) : Error: undefined label =
'ThisIsABogusVariable'--- errorlevel 1
This is what should have been expected.

To make both DM and BC compilers happy, and also 16-bit and 32-bit =
source level compatible,
this is the fix:
void someobj::somebuggyfunction(){    unsigned char uc =3D m_cC;    // =
Use the stack to get member variable    __asm   mov dx, 0x300    __asm   =
mov al, uc          // Now both 16-bit and 32-bit is OK... (I think)    =
__asm   out dx,al}


Have a nice day Walter.  ;-)
Aug 07 2002
parent Jan Knepper <jan smartsoft.cc> writes:
KarL wrote:

 NO. It shouldn't even compile at all! somepublicfunction() is
 a global function and is unable to even see m_cC!

Are you sure it's not just reserving an 'int' somewhere? Jan
Aug 07 2002
prev sibling parent reply "Walter" <walter digitalmars.com> writes:
Content-Type: text/plain;
	charset="iso-8859-1"
Content-Transfer-Encoding: quoted-printable

Lookup rules in inline asm are a little different. All struct members =
are included in the search, regardless of protection attributes, =
scoping, etc. This sounds a little wierd, but is intentional. It's =
fallout from trying to emulate MASM syntax, and MASM has little concept =
of structs, scoping, etc. Secondly, all struct members resolve to simply =
an integer representing the offset of that member from the start of the =
struct. This is so that it can be used as an offset to whatever 'this' =
value is in the index register:

    mov EAX, foo[ECX]

I hope this clears up the confusion.

-Walter


  "KarL" <someone somewhere.org> wrote in message =
news:aiq0sh$d69$1 digitaldaemon.com...
  Source:
  The "somepublicfunction" did not report the error on using m_cC in the =
inline assembly - since
  m_cC is not declared as a global variable.
  The same thing with someobj::somepublicfunction which failed to =
generate the someobj::m_cC
  reference.
  someobj::somefunction appears to be OK.
Aug 07 2002
next sibling parent reply "KarL" <someone somewhere.org> writes:
Content-Type: text/plain;
	charset="iso-8859-1"
Content-Transfer-Encoding: quoted-printable

  Walter <walter digitalmars.com> wrote in message =
news:aisitv$29es$1 digitaldaemon.com...
  Lookup rules in inline asm are a little different. All struct members =
are included in the search, regardless of protection attributes, =
scoping, etc. This sounds a little wierd, but is intentional. It's =
fallout from trying to=20
Heh heh heh, I did say the word "Wierd" in the subject of this post.
  emulate MASM syntax, and MASM has little concept of structs, scoping, =
etc. Secondly, all struct members resolve to simply an integer =
representing the offset of that member from the start of the struct. =
This is so that it can be used as an offset to whatever 'this' value is =
in the index register:
  =20
      mov EAX, foo[ECX]
  =20
  I hope this clears up the confusion.
  =20
  -Walter
I did figured it out (see the other post).  Basically maintaining =
"source level compatibility"
across compilers and cpu target is never easy the moment inline =
assemblies are used.
Aug 07 2002
parent "Walter" <walter digitalmars.com> writes:
Content-Type: text/plain;
	charset="iso-8859-1"
Content-Transfer-Encoding: quoted-printable

You're right. That is why in the D language, the inline assembler is =
specified.

  "KarL" <someone somewhere.org> wrote in message =
news:aisl3m$2bqa$1 digitaldaemon.com...
    I did figured it out (see the other post).  Basically maintaining =
"source level compatibility"
  across compilers and cpu target is never easy the moment inline =
assemblies are used.
Aug 07 2002
prev sibling parent "KarL" <someone somewhere.org> writes:
Content-Type: text/plain;
	charset="iso-8859-1"
Content-Transfer-Encoding: quoted-printable

Lastly, if I recompile using Borland compiler:
C:\tmp\bugtest>bcc -c bug.cppBorland C++ 5.0 Copyright (c) 1987, 1996 =
Borland Internationalbug.cpp:Error bug.cpp 11: Undefined symbol 'm_cC' =
in function somepublicfunction()Warning bug.cpp 13: Function should =
return a value in function somepublicfunction()*** 1 errors in Compile =
***
Borland did pick up the error!  So this is not only the assembly syntax =
compatibilities.

  Walter <walter digitalmars.com> wrote in message =
news:aisitv$29es$1 digitaldaemon.com...
  Lookup rules in inline asm are a little different. All struct members =
are included in the search, regardless of protection attributes, =
scoping, etc. This sounds a little wierd, but is intentional. It's =
fallout from trying to emulate MASM syntax, and MASM has little concept =
of structs, scoping, etc. Secondly, all struct members resolve to simply =
an integer representing the offset of that member from the start of the =
struct. This is so that it can be used as an offset to whatever 'this' =
value is in the index register:
  =20
      mov EAX, foo[ECX]
  =20
  I hope this clears up the confusion.
  =20
  -Walter
Aug 07 2002