🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: gnu.gcc.bug
Article #5974

asm(): Gcc used clobbered regs for i/o operands

#5974
From: Michael Hohmuth
Date: Fri, 17 Jan 1997 00:00
176 lines
4993 bytes
I have a problem with Gcc's inline assmbler facility (gcc-2.7.2.1,
i486-linux).  Under some circumstances, given an inline assembler
statement like:

  __asm__ __volatile__ 
    ("
      mov $0xdeadbeef, %%eax
      mov $0x12345678, %%ebx
      mov %1, %%eax
      mov %%ebx, %0
      "
     : "=r" (b)
     : "r" (a)
     : "eax", "ebx"
     );

the compiler will generate code like:

  #APP
      mov $0xdeadbeef, %eax
      mov $0x12345678, %ebx
      mov %ebx, %eax
      mov %ebx, %ebx
  #NO_APP

As you see, the compiler has allocated registers %eax and %ebx for
input/output even though we've explicitly specified these registers as
scratch registers.

Full source code and Gcc-generated assembler text follows after my
signature.

Some more details:

- System is Debian GNU/Linux 1.2.  "uname -a" yields:

  Linux os 2.0.27 #2 Sun Dec 15 16:29:14 MET 1996 i686

  Debian configures the compiler sources using "./configure
  --prefix=/usr i486-linux".

- "gcc -v" fields:

  Reading specs from /usr/lib/gcc-lib/i486-linux/2.7.2.1/specs
  gcc version 2.7.2.1

- The bug only seems to occur for the example included below when
  compiling without "-O".  However, we've also experienced this bug
  with other (more complicated) sources when compiling with "-O".

Michael
-- 
Email: hohmuth@inf.tu-dresden.de
WWW:   http://www.inf.tu-dresden.de/~mh1/

foo.c:

------------------------------------------------------------------------------
int foo(int a)
{
  int b;

  __asm__ __volatile__
    ("nop"
     : "=b" (a)
     : "0" (a)
     );

  __asm__ __volatile__ 
    ("
      mov $0xdeadbeef, %%eax
      mov $0x12345678, %%ebx
      mov %1, %%eax
      mov %%ebx, %0
      "
     : "=r" (b)
     : "r" (a)
     : "eax", "ebx"
     );

  return b;
}
------------------------------------------------------------------------------

The first __asm__ statement is just a no-op and causes Gcc to hold
variable "a" in the %ebx register.

The command "gcc -g -S foo.c" generated this assembler text:

------------------------------------------------------------------------------
	.file	"foo.c"
	.version	"01.01"
.stabs "/home/hohmuth/src/gcc-bug/",100,0,0,.Ltext0
.stabs "foo.c",100,0,0,.Ltext0
.text
.Ltext0:
	.stabs	"gcc2_compiled.", 0x3c, 0, 0, 0
.stabs "int:t1=r1;-2147483648;2147483647;",128,0,0,0
.stabs "char:t2=r2;0;127;",128,0,0,0
.stabs "long int:t3=r1;-2147483648;2147483647;",128,0,0,0
.stabs "unsigned int:t4=r1;0;-1;",128,0,0,0
.stabs "long unsigned int:t5=r1;0;-1;",128,0,0,0
.stabs "long long int:t6=r1;01000000000000000000000;0777777777777777777777;",128,0,0,0
.stabs "long long unsigned int:t7=r1;0000000000000;01777777777777777777777;",128,0,0,0
.stabs "short int:t8=r1;-32768;32767;",128,0,0,0
.stabs "short unsigned int:t9=r1;0;65535;",128,0,0,0
.stabs "signed char:t10=r1;-128;127;",128,0,0,0
.stabs "unsigned char:t11=r1;0;255;",128,0,0,0
.stabs "float:t12=r1;4;0;",128,0,0,0
.stabs "double:t13=r1;8;0;",128,0,0,0
.stabs "long double:t14=r1;12;0;",128,0,0,0
.stabs "complex int:t15=s8real:1,0,32;imag:1,32,32;;",128,0,0,0
.stabs "complex float:t16=r16;4;0;",128,0,0,0
.stabs "complex double:t17=r17;8;0;",128,0,0,0
.stabs "complex long double:t18=r18;12;0;",128,0,0,0
.stabs "void:t19=19",128,0,0,0
	.align 16
.stabs "foo:F1",36,0,2,foo
.stabs "a:p1",160,0,1,8
.globl foo
	.type	 foo,@function
foo:
.stabn 68,0,2,.LM1-foo
.LM1:
	pushl %ebp
	movl %esp,%ebp
	subl $4,%esp
	pushl %ebx
.stabn 68,0,3,.LM2-foo
.LM2:
.LBB2:
.stabn 68,0,5,.LM3-foo
.LM3:
	movl 8(%ebp),%ebx
#APP
	nop
#NO_APP
	movl %ebx,8(%ebp)
.stabn 68,0,11,.LM4-foo
.LM4:
	movl 8(%ebp),%ebx
#APP
	
      mov $0xdeadbeef, %eax
      mov $0x12345678, %ebx
      mov %ebx, %eax
      mov %ebx, %ebx
      
#NO_APP
	movl %ebx,-4(%ebp)
.stabn 68,0,23,.LM5-foo
.LM5:
	movl -4(%ebp),%eax
	jmp .L1
	.align 16
.stabn 68,0,24,.LM6-foo
.LM6:
.LBE2:
.stabn 68,0,24,.LM7-foo
.LM7:
.L1:
	movl -8(%ebp),%ebx
	movl %ebp,%esp
	popl %ebp
	ret
.Lfe1:
	.size	 foo,.Lfe1-foo
.stabs "b:1",128,0,3,-4
.stabn 192,0,0,.LBB2-foo
.stabn 224,0,0,.LBE2-foo
	.text
	.stabs "",100,0,0,.Letext
.Letext:
	.ident	"GCC: (GNU) 2.7.2.1"
------------------------------------------------------------------------------
Technical Details
Message-ID: <199701171254.NAA00642@os.inf.tu-dresden.de>
Path: arc1-ca.pugleaf.net!unknown!not-for-mail

Show Full Headers
Complete Article Headers
X-Google-Language: ENGLISH,ASCII-7-bit
X-Google-Thread: 113d02,ae7e1eb2b402fda7,start
X-Google-Attributes: gid113d02,public
From: hohmuth@inf.tu-dresden.de (Michael Hohmuth)
Subject: asm(): Gcc used clobbered regs for i/o operands
Date: 1997/01/17
Message-ID: <199701171254.NAA00642@os.inf.tu-dresden.de>
X-Deja-AN: 210517216
sender: bug-gcc-request@prep.ai.mit.edu
content-type: text/plain; charset=US-ASCII
organization: Dept. of Computer Science, TU Dresden, Germany
x-gateway: relay6.UU.NET from bug-gcc to gnu.gcc.bug; Fri, 17 Jan 1997 08:23:04 EST
mime-version: 1.0
newsgroups: gnu.gcc.bug
x-mailer: ELM [version 2.4ME+ PL28 (25)]