Thread overview
Wierd behaviour with mixed ASM and C++
Aug 07, 2002
KarL
Aug 07, 2002
Roland
Aug 08, 2002
KarL
Aug 08, 2002
Jan Knepper
Aug 08, 2002
Walter
Aug 08, 2002
KarL
Aug 08, 2002
Walter
Aug 08, 2002
KarL
August 07, 2002
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 = 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.


August 07, 2002

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




August 08, 2002
  Roland <rv@ronetech.com> wrote in message news:3D50F00A.EBF0567@ronetech.com...

  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

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 = 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 = 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.  ;-)


August 08, 2002
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



August 08, 2002
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.


August 08, 2002
  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
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:

      mov EAX, foo[ECX]

  I hope this clears up the confusion.

  -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.


August 08, 2002
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.


August 08, 2002
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:

      mov EAX, foo[ECX]

  I hope this clears up the confusion.

  -Walter