KnowledgeBase Archive

An Archive of Early Microsoft KnowledgeBase Articles

View on GitHub

Q40756: Bad Code for Expression Parameter of outp() with -Oi

Article: Q40756
Product(s): See article
Version(s): 5.10
Operating System(s): MS-DOS
Keyword(s): ENDUSER | SR# G881205-7390 | mspl13_c
Last Modified: 15-JAN-1990

When compiling the source line below, the Microsoft C Compiler Version
5.10 generates incorrect code in some cases for the intrinsic outp and
outpw functions when the -Oi option is used and the second parameter
is an expression. Workarounds are listed below.

The following is the C source line and the generated code:

        outp(port + INT_ENABLE_OFF, (i == SIO_CNT) ? 3 : 1);

            cmp    WORD PTR [bp-6], 8                     ;i
            je    $L20003                                 ;error !
            mov   ax, 3
            jmp   SHORT $L20004
$L20003:
            mov   ax, 1
$L20004:
            push  ax
            mov   ax,   WORD PTR [bp-4]                   ;port
            inc   ax
            push  ax
            call  FAR PTR _outp

This assembly code would be equal to a source line such as the
following:

   outp(port + IN_ENABLE_OFF, (i == SIO_CNT) ? 1 : 3);

This is the exact reverse of the original source line. Therefore, the
generated assembler code should read as follows:

            cmp    WORD PTR [bp-6], 8                     ;i
            jne    $L20003                                ;
            mov   ax, 3
            jmp   SHORT $L20004
$L20003:
            mov   ax, 1
$L20004:
            push  ax
            mov   ax,   WORD PTR [bp-4]                   ;port
            inc   ax
            push  ax
            call  FAR PTR _outp

There are two workarounds:

1. Use a temporary variable -- for example:

       x = (i == SIO_CNT) ? 1 : 3;
       outp(port + stuff, x);

2. Don't use -Oi.

3. Use -Oi, but use the "#pragma function(outp outpw)" statement to
   have the non-intrinsic version of the function used.

THE INFORMATION PROVIDED IN THE MICROSOFT KNOWLEDGE BASE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. MICROSOFT DISCLAIMS ALL WARRANTIES, EITHER EXPRESS OR IMPLIED, INCLUDING THE WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL MICROSOFT CORPORATION OR ITS SUPPLIERS BE LIABLE FOR ANY DAMAGES WHATSOEVER INCLUDING DIRECT, INDIRECT, INCIDENTAL, CONSEQUENTIAL, LOSS OF BUSINESS PROFITS OR SPECIAL DAMAGES, EVEN IF MICROSOFT CORPORATION OR ITS SUPPLIERS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. SOME STATES DO NOT ALLOW THE EXCLUSION OR LIMITATION OF LIABILITY FOR CONSEQUENTIAL OR INCIDENTAL DAMAGES SO THE FOREGOING LIMITATION MAY NOT APPLY.

Copyright Microsoft Corporation 1986-2002.