#1384 When using Intel syntax, GCC assembles wrong address for jne

gcc (462)

When I compile this code:
--------[ reduced.cpp ]--------
int Foo(char * b)
int l = 1234;
int ul = 0;
for(; l; l--, b++) ul += *b;
return ul;
--------[ EOF ]--------
For example using:
$ gcc reduced.cpp -S reduced.s -Os -fomit-frame-pointer -masm=intel;start reduced.s &
(-fomit-frame-pointer is not necessary to make the problem happen but makes the output easier to read.)
I get the following output, which I believe to be correct:
--------[ reduced.s ]--------
.file "reduced.cpp"
.intel_syntax noprefix
.globl __Z3FooPc
.def __Z3FooPc; .scl 2; .type 32; .endef
push ebx
mov ecx, DWORD PTR [esp+8]
xor edx, edx
xor eax, eax
movsx ebx, BYTE PTR [ecx+edx]
add eax, ebx
inc edx
cmp edx, 1234
jne L2
pop ebx
--------[ EOF ]--------
Note that the jne instruction points to the movsx instruction.
When I assemble, for example using the -c (or -o) option:
$ gcc reduced.cpp -c -Os -fomit-frame-pointer -masm=intel;objdump -d reduced.o -Mintel > dump.txt;start dump.txt &
--------[ dump.txt ]--------

reduced.o: file format pe-i386

Disassembly of section .text:

00000000 <__Z3FooPc>:
0: 53 push ebx
1: 8b 4c 24 08 mov ecx,DWORD PTR [esp+0x8]
5: 31 d2 xor edx,edx
7: 31 c0 xor eax,eax
9: 0f be 1c 11 movsx ebx,BYTE PTR [ecx+edx*1]
d: 01 d8 add eax,ebx
f: 42 inc edx
10: 81 fa d2 04 00 00 cmp edx,0x4d2
16: 75 fa jne 12 <__Z3FooPc+0x12>
18: 5b pop ebx
19: c3 ret
1a: 90 nop
1b: 90 nop
--------[ EOF ]--------
Note that the jne is now pointing halfway the cmp instruction. In a finished program this typically results in an access violation or illegal instruction exception. It was quite baffling.

The -Os switch is required in this case because otherwise it generates different code. However, since the generated assembler output appears correct I don't think this is an optimiser bug.
The -masm=intel switch is required. When I tried AT&T syntax it did generate the right address. (Unfortunately this was reduced from code that also contains Intel syntax asm("...") statements. AT&T syntax looks like line noise to me, so I guess I'll try to massage the code until it stops doing this.)
OS: WinXP, up-to-date. I tried to reproduce the problem on Debian GNU/Linux, which is still using 4.3 and the problem didn't happen there.
$ gcc -v
Using built-in specs.
Target: mingw32
Configured with: ../gcc-4.4.0/configure --enable-languages=c,ada,c++,fortran,java,objc,obj-c++ --disable-sjlj-exceptions --enable-shared --enable-libgcj --enable-libgomp --with-dwarf2 --disable-win32-registry --enable-libstdcxx-debug --enable-version-specific-runtime-libs --prefix=/mingw --with-gmp=/mingw/src/gmp/root --with-mpfr=/mingw/src/mpfr/root --build=mingw32
Thread model: win32
gcc version 4.4.0 (GCC)
$ ld -v
GNU ld (GNU Binutils) 2.20
$ uname -a
MINGW32_NT-5.1 [ snip ] 1.0.10(0.46/3/2) 2004-03-15 07:17 i686 unknown

I searched the existing bugs using all the relevant keywords I could think of - however, I found nothing so I decided to report this as a new bug. Many thanks in advance; I hope this will help you improve GCC.


  • Shinobu Maehara

    Shinobu Maehara - 2010-02-01

    I've had the same thing happen today with an unconditional jmp.
    f2b: e9 2f ff ff ff jmp e5f
    Again the destination was pointing halfway an instruction.

  • Earnie Boyd

    Earnie Boyd - 2012-10-21

    This isn't true for the 4.7.0 version.

  • Earnie Boyd

    Earnie Boyd - 2012-10-21
    • status: open --> closed-fixed

Get latest updates about Open Source Projects, Conferences and News.

Sign up for the SourceForge newsletter:

No, thanks