ID Number: Q40756
5.10
MS-DOS
buglist5.10 fixlist6.00
Summary:
When compiling the source line below, the Microsoft C Compiler version
5.1 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.
Microsoft has confirmed this to be a problem in C version 5.1. This
problem was corrected in C version 6.0.
More Information:
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 three workarounds:
1. Use a temporary variable -- for example:
x = (i == SIO_CNT) ? 1 : 3;
outp(port + stuff, x);
2. Do not use -Oi.
3. Use -Oi, but use the "#pragma function(outp outpw)" statement to
have the non-intrinsic version of the function used.