Bana bağlantı kaydının değerini neden test ettiğimizi anlatabilir misiniz?
bl check_position
bağlantı sicilinde
PC+4
değerini yerleştirin ve
check_position
da PC akrabasına kontrolünü aktaracaktır. Şu ana kadar her şey
PC
göreceli olarak
bl at ARM.
ldr r1,=check_position
, literal havuzdan bir değer alır.
ldr r1,[pc, #offset]
...
offset:
.long check_position # absolute address from assemble/link.
Yani R0
PC bağlı sürümünü içerir ve R1
mutlak monte sürümünü içeren, gibi Ref1 gerçek kod görünüyor. Burada karşılaştırıldılar. Ayrıca, farkı hesaplamak için aritmetik kullanabilir ve şubesi sıfır değilse; ya da muhtemelen kodu mutlak hedefe kopyalayın. de çalışan Ref2 kodu ise R0
ve R1
aynıdır, sonra adresini bağladı. Bu, bl
için bazı pseudo code
.
mov lr,pc ; pc is actually two instruction ahead.
add pc,pc,#branch_offset-8
anahtar BL
lr
güncellenirken dahil PC
dayalı her şeyi yapmasıdır. Bu numarasını kullanmak yerine mov R0,PC
kullanabiliriz, ancak PC
8 bayttır. Başka bir alternatif ise, adr R0,check_position
'u kullanmaktır, bu da assembler'ın bizim için tüm adres matematiğini yapmasını sağlar.
/* 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
Ref1: gnu-montajcı kılavuzuna
Ref2 içinde Arm op-codes ve .ltorg bakınız: Bu Linux head.S
ARM için yaptığını tam olarak ne olduğunu.
Düzenleme: ARM ARM'ı kontrol ettim ve PC, kodun neden böyle olduğunu göstermek için geçerli olan geçerli komut +8
. Ben adr
sürümü daha doğrudan ve okunabilir olduğunu düşünüyorum, ancak adr
sözde op çoğu kez bu yüzden insanlar aşina olmayabilir bu yüzden kullanılmaz.
Mükemmel iki cevap için teşekkür ederiz! Her ikisini de kabul edersem, çünkü kodun amacını (JTAG program yükleyici varsayımı doğru) ve ikincisi tam olarak nasıl çalıştığını açıklar. –