I think the problem here (at least on Linux) might be gdb trying to help out, from the docs:
set disable-randomization
set disable-randomization on
This option (enabled by default in gdb) will turn off the native randomization of the
virtual address space of the started program. This option is useful for multiple debugging
sessions to make the execution better reproducible and memory addresses reusable across
debugging sessions.
This feature is implemented only on gnu/Linux. You can get the same behavior using
(gdb) set exec-wrapper setarch `uname -m` -R
http://sourceware.org/gdb/current/onlinedocs/gdb/Starting.html
UPDATE: I've now checked this and it does seem to be the case for me (running Linux 2.6.28). Compile a simple Hello World program and start gdb with no command-line args (we don't want to load the program before overriding the disable-randomization setting) and then enter:
(gdb) set disable-randomization off
(gdb) file ./a.out
(gdb) break main
(gdb) run
(gdb) disas printf
The address of printf is different each time the program is run.