From mboxrd@z Thu Jan 1 00:00:00 1970 From: "Christian Häggström" <97nv46@skola.kiruna.se> To: Subject: Volatile constants? Date: Tue, 22 Feb 2000 00:52:00 -0000 Message-id: X-SW-Source: 2000-02/msg00625.html 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,