Qualcuno può spiegarmi perché testiamo qui il valore del registro di collegamento?
Il bl check_position
posizionerà il valore di PC+4
nel registro link per trasferire il controllo al check_position
relativa anche PC. bl at ARM Finora tutto è PC
relativo.
ldr r1,=check_position
riceve un valore dal pool letterario . Rif1 Il codice attuale sembra,
ldr r1,[pc, #offset]
...
offset:
.long check_position # absolute address from assemble/link.
Così il R0
contiene una versione relativa PC e il R1
contiene la versione in assoluto assemblato. Qui, sono confrontati. È anche possibile utilizzare l'aritmetica per calcolare la differenza e quindi ramo se non zero; o possibilmente copiare il codice nella sua destinazione assoluta. Ref2 Se il codice è in esecuzione allo indirizzo, quindi R0
e R1
sono gli stessi. Questo è un po 'pseudo code
per bl
.
mov lr,pc ; pc is actually two instruction ahead.
add pc,pc,#branch_offset-8
La chiave è che BL
fa tutto in base alla PC
compreso l'aggiornamento di lr
. Invece di usare questo trucco , potremmo usare mov R0,PC
, eccetto lo PC
con 8 byte di anticipo. Un'altra alternativa sarebbe quella di usare adr R0,check_position
, che farebbe sì che l'assemblatore faccia tutti gli indirizzi matematici per noi.
/* Test if we are running from an address, we are not linked at */
check_position:
adr r0, check_position
ldr r1, =check_position
cmp r0, r1 /* ; don't relocate during debug */
beq relocated_entry
Rif1: Vedi Arm op-codes e .ltorg nel manuale di GNU-assemblatore
Rif2: Questo è esattamente ciò che il Linux head.S
sta facendo per l'ARM.
Modifica: Ho controllato il BRACCIO ARM e il PC è apparentemente l'istruzione corrente +8
, che va a mostrare perché il codice era come questo. Penso che la versione adr
sia più diretta e leggibile, ma la pseudo-op adr
non viene utilizzata più spesso così le persone potrebbero non averne familiarità.
Grazie per le due eccellenti risposte! Accetterei entrambi se coud, dal momento che uno spiega l'obiettivo del codice (l'ipotesi del programma di caricamento del programma JTAG è corretta) e il secondo come funziona esattamente. –