The following piece of code is from u-boot:
/* Initialize GOT pointer.
** Global symbols can't be resolved before this is done, and as such we can't
** use any global symbols in this code. We use the bal/ move xxx,ra combination to access
** data in a PC relative manner to avoid this. This code will correctly set the
** gp regardless of whether the code has already been relocated or not.
** This code determines the current gp by computing the link time (gp - pc)
** and adding this to the current pc. 开发者_如何学Python
** runtime_gp = runtime_pc + (linktime_gp - linktime_pc)
** U-boot is running from the address it is linked at at this time, so this
** general case code is not strictly necessary here.
*/
/*Branch and link to get current PC in ra */
bal 1f
nop
.extern _GLOBAL_OFFSET_TABLE_
.word _GLOBAL_OFFSET_TABLE_ /* This contains the linked address of the GOT */
/* The ra register now contains the runtime address of the above memory location */
.word . - 4 /* This contains the link time address of the previous word,
which is also what the link time expected PC value is */
1:
move gp, ra /* Move current PC into gp register */
lw a5, 0(ra) /* Load linked address of the GOT into a5 */
lw a6, 4(ra) /* Load the link time address of the GOT storage location into a6 */
sub a5, a6 /* Subtract a6 from t1. */
/* a5 now contains the difference between the link-time GOT table address and the link time expected PC */
/* Add this difference to the current PC (copied into gp above) so that gp now has the current runtime
** GOT table address */
daddu gp, a5 # calculate current location of offset table
I don't understand 3 directive above:
.extern _GLOBAL_OFFSET_TABLE_
.word _GLOBAL_OFFSET_TABLE_ //what the meaning after declaring it as a external symbol?
.word . -4 //and also this one?
TIA
.extern _GLOBAL_OFFSET_TABLE_
The symbol is described outside of this compilation unit. Resolve it at link time.
.word _GLOBAL_OFFSET_TABLE_
Allocate a word worth of memory and place the address of the symbol at this location
.word . - 4
Take the current location, .
, subtract 4 and place that value in a word of memory. Similar to the previous code except the value being placed at this location is being computed.
Here is a link with a list of many of the assembler directives.
精彩评论