Re: [BUG FIX] Make x86_32 uni-processor Atomic ops, Atomic

From: Michael S. Zick
Date: Tue May 26 2009 - 08:37:45 EST

On Mon May 25 2009, H. Peter Anvin wrote:
> Michael S. Zick wrote:
> >
> > Load Effective Address does two's complement arithmetic?
> > I'll take your word for it.
> >
> LEA, and all other address calculations use 2's-complement arithmetic:
> leal -1(%ebx),%eax
> leal 0xffffffff(%ebx),%eax
> ... is the same instruction.
> However, gcc has been known to optimize out range checks when operating
> on signed integers; it is allowed to do this by the C standard, but it
> can give surprising results if the user expected wraparound.

Well, it isn't a range check - - but this illustrates where my (false)
concern came from:

Given this input file:
extern int diff_umask(int mask, int *cnt1, int *cnt2)
{ return (((mask - *cnt1) + *cnt2) & mask); }

gcc -O2 -S -fomit-frame-pointer difftest.c

Yields (as difftest.s):
.file "difftest.c"
.p2align 4,,15
.globl diff_umask
.type diff_umask, @function
movl 12(%esp), %eax
movl 4(%esp), %ecx
movl (%eax), %edx
leal (%ecx,%edx), %eax
movl 8(%esp), %edx
subl (%edx), %eax
andl %ecx, %eax
.size diff_umask, .-diff_umask
.ident "GCC: (Debian 4.3.2-1.1) 4.3.2"
.section .note.GNU-stack,"",@progbits

How follow that up with the commands:
gcc -O2 -c -fomit-frame-pointer difftest.s

Then examine the result with objdump:
objdump -d difftest.o

In relevant part, yields:
difftest.o: file format elf32-i386

Disassembly of section .text:

00000000 <diff_umask>:
0: 8b 44 24 0c mov 0xc(%esp),%eax
4: 8b 4c 24 04 mov 0x4(%esp),%ecx
8: 8b 10 mov (%eax),%edx
a: 8d 04 11 lea (%ecx,%edx,1),%eax
d: 8b 54 24 08 mov 0x8(%esp),%edx
11: 2b 02 sub (%edx),%eax
13: 21 c8 and %ecx,%eax
15: c3 ret

= = = =

Checking the byte string 0x8d, 0x04, 0x11 against the Intel
documentation shows that the disassembly output of objdump
is incorrect - that bit string does not have an offset field.
That is the byte encoding for the gcc assembly input.

What's a person to do when the tool-chain lies?

> -hpa

To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at
Please read the FAQ at