Bug 33527 - GCC doesn't protect %edi when using inline assembly
Summary: GCC doesn't protect %edi when using inline assembly
Status: RESOLVED INVALID
Alias: None
Product: gcc
Classification: Unclassified
Component: c (show other bugs)
Version: 4.1.2
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2007-09-22 06:59 UTC by Mike Meng
Modified: 2007-09-22 07:27 UTC (History)
2 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Mike Meng 2007-09-22 06:59:34 UTC
OS: Ubuntu 7.04
GCC version: 4.2.1

I try to play the inline assembly function. Here I use "rep movsb" to copy a string.

// Code begin
char input[] = {"GCC Version Number"};
char output[30];
int  length = 28;

asm (
  "cld\n\t"
  "rep movsb"
  :
  : "c"(length), "S"(input), "D"(output));

printf("%s\n", output);
// Code end

  While compiled without "-O", everything is okay. However, if compiled with "-O", the compiler will generate incorrect code as if the %edi never changes during the assembly code execution.

Compile with "-S" will see the corresponding generated assembly codes are:

// code begin
# APP
  cld
  rep movsb
# NO_APP
  movl %edi, -4(%esp)  # BAD CODE HERE
  movl $.LC1, (%esp)
  call printf 
// code end

The problem is, movsb changes the value of %esi and %edi, and I told the compiler about this in the "input" section in the asm directive. The compiler didn't notice this and believe the value of %edi unchanged. 

I think this is a bug.
Comment 1 Eric Botcazou 2007-09-22 07:27:41 UTC
> The problem is, movsb changes the value of %esi and %edi, and I told the
> compiler about this in the "input" section in the asm directive.

No, you didn't, you only told that %esi and %edi should be loaded on entry.

See section 5.35 of the manual, especially the paragraph starting with "Some
instructions clobber specific hard registers".  Note that the provision "You
may not write a clobber description in a way that overlaps with an input or
output operand" will apply in this case, so 'volatile' will be required.
Comment 2 Eric Botcazou 2007-09-22 10:22:33 UTC
Subject: Re:  GCC doesn't protect %edi when using inline assembly

> I've tried 'volatile', but it doesn't work.

#include <stdio.h>

int main(void)
{
char input[] = {"GCC Version Number"};
char output[30],*dummy;
int  length = 28;

asm volatile (
  "cld\n\t"
  "rep movsb"
  : "=S"(dummy),"=D"(dummy)
  : "c"(length), "0"(input), "1"(output));

printf("%s\n", output);

return 0;
}