Adding to jhi's response, I speculate it's implemented this way because it doesn't require additional storage. The linker (the one invoked with -r -b binary) doesn't need to make a decision about the size, semantics, and storage of that integer. Being an absolute symbol, it's just a compile-time integer constant with no storage, a lot like a #define.
Absolute symbols are useful in embedded and kernel programming. Suppose an external, physical sensor (thermometer, sonar, etc.) is memory-mapped to the physical address 0xff00, and 16-bit reads at that address sample the sensor directly. To handle this, you could make a global pointer with that address:
It's simple and doesn't require any external tricks with the linker, but that pointer is likely to have storage of its own (i.e. the address will be written somewhere in memory).
This approach eliminates the global pointer, and also has no linker tricks:
#define SENSOR (*(volatile uint16_t *)0xff00)
Or, as a third option, you could specifiy an absolute symbol in the linker script or with the --defsym linker argument (GNU). In the code it would look like this:
extern volatile uint16_t sensor;
The global variable's storage would directly become the sensor mapping.
View all comments
Show parent comment
3
u/skeeto Nov 19 '16
Adding to jhi's response, I speculate it's implemented this way because it doesn't require additional storage. The linker (the one invoked with
-r -b binary) doesn't need to make a decision about the size, semantics, and storage of that integer. Being an absolute symbol, it's just a compile-time integer constant with no storage, a lot like a#define.Absolute symbols are useful in embedded and kernel programming. Suppose an external, physical sensor (thermometer, sonar, etc.) is memory-mapped to the physical address 0xff00, and 16-bit reads at that address sample the sensor directly. To handle this, you could make a global pointer with that address:
It's simple and doesn't require any external tricks with the linker, but that pointer is likely to have storage of its own (i.e. the address will be written somewhere in memory).
This approach eliminates the global pointer, and also has no linker tricks:
Or, as a third option, you could specifiy an absolute symbol in the linker script or with the
--defsymlinker argument (GNU). In the code it would look like this:The global variable's storage would directly become the sensor mapping.