What is the difference between position-dependent code and position-independent code?
And also how can we implement / invoke our own static and dynamic libraries with example?
What is the difference between position-dependent code and position-independent code?
And also how can we implement / invoke our own static and dynamic libraries with example?
In early computers, code was position-dependent: each program was built to be loaded into, and run from, a particular address. In order to run multiple jobs using separate programs at the same time, an operator had to carefully schedule the jobs so that no two simultaneous jobs would run programs that required the same load addresses.
For example, if both the payroll program and the accounts receivable program were built to run at address 32K, the operator could not run both at the same time. Sometimes, an operator would keep multiple versions of a program around, each built for a different load address, to expand his options.
To make things more flexible, position-independent code was invented. Position-independent code could run from any address at which the operator chose to load it. Position-independent code has been used not only to coordinate the work of user-level applications, but within operating systems as well.
Position independent code can run correctly wherever the code is loaded in the memory. This is usually achieved by using relative jumps for function calls, with relative jumps, the jump address is calculated from the current position in the code stream so the code might look like: "jump 585 bytes from the current position" or "jump 5745 bytes from the base address of this module" instead of "jump to address 0x46fae55". Likewise for any other instructions that references memory address has to be written relative to the current code position or relative to a base address that is determined at runtime.
The use of Memory Management Unit (MMU) and virtual memory address makes position independent code almost obsolete for executables. Shared libraries though, have to be written as position independent code because they can be mapped to any position in the address space of the executables.
To add to the answer of Lie Ryan -- This is not a matter of c programming language, but of the system architecture.
E.g. intel x86 segmented architecture supported semi-automatically position independent loading of small executables in .com format, where the OS could load cs=ds=es=ss to 2^16 different values.
The .exe format OTOH introduced 'relocation', which meant that in the executable there is an array of offsets (relative to the loading address of the binary), that has to added with the loading address: eg.
relocation_table: // list of values to be modified
0022, 0100, ...
.text
0020: xx yy 12 00 mov ax,[0x0012] <-- the "absolute address" 0012 is
// located at address 0022 in the binary -- that has to be added with the real
// location of the the "position-independent" code