This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Volatile constants?


compiling this code

   extern void f() asm("f");
   void f() {}
   int end = (int)f + 256;

gives as expected this assembly output (shortened)

.text
f:
	ret
.data
end:
	.long f+256

That looks fine, but I wish to right shift the adress to f()

   int seg = (int)f >> 16;

This gives the far more ugly code (some labels removed)

.bss
seg:
	.zero	4
.text
__static_initialization_and_destruction_0:
	cmpl $65535,12(%ebp)
	jne .L8
	cmpl $0,8(%ebp)
	je .L8
	movl $f__Fv,%eax
	sarl $16,%eax
	movl %eax,seg
	ret
_GLOBAL_.I.f:
	subl $8,%esp
	addl $-8,%esp
	pushl $65535
	pushl $1
	call __static_initialization_and_destruction_0
	ret
.section	.ctors,"aw"
	.long	 _GLOBAL_.I.f

	.ident	"GCC: (GNU) 2.95.2 19991024 (release)"

Why? Can ld only handle + and -, and not << >> * / and other operators?

Anyway, I have found and use a way to work around this:
1. Substitute the expression with a symbol
2. Calculate the exression in a ld script

The above example becomes:

   extern int f_rsh_16;
   int seg = (int)&f_rsh_16;

and then I run the linker script

   SECTIONS {
      f_rsh_16 = f >> 16;
   }

This way is very ugly, does anybody know a better way?

$ ld -v
GNU ld version 2.9.5 (with BFD 2.9.5.0.16)

I reconfigured gcc with --with-gnu-ld, but it was the same thing.

Maybe this is a linker limitation... Does GNU ld have a mailing list?

Best regards, <mrz@hehe.com>


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]