This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
Volatile constants?
- To: <gcc at gcc dot gnu dot org>
- Subject: Volatile constants?
- From: "Christian Häggström" <97nv46 at skola dot kiruna dot se>
- Date: Tue, 22 Feb 2000 09:51:50 +0100
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>