Ada banyak situs dan contoh lainnya. Ribuan jika tidak puluhan ribu. Ada c library yang terkenal dengan skrip linker dan kode boostrap, newlib, glibc khususnya tetapi ada yang lain yang dapat Anda temukan. Bootstraping C dengan C tidak masuk akal.
Pertanyaan Anda telah dijawab, Anda mencoba melakukan perbandingan tepat pada hal-hal yang mungkin tidak tepat, mungkin tidak dimulai pada batas yang diketahui atau berakhir pada batas yang diketahui. Jadi Anda dapat melakukan hal yang kurang dari itu tetapi jika kode tidak bekerja dengan perbandingan yang tepat maka itu berarti Anda mem-posting .bss ke bagian berikutnya yang mungkin atau mungkin tidak menyebabkan hal-hal buruk terjadi, jadi cukup ganti dengan yang kurang dari bukan solusinya.
Jadi begini TL; DR baik-baik saja. Anda tidak mem-bootstrap bahasa dengan bahasa itu, Anda bisa lolos dengan itu, tetapi Anda bermain dengan api saat melakukannya. Jika Anda baru belajar bagaimana melakukan ini, Anda harus berhati-hati, bukan keberuntungan bodoh atau fakta yang belum Anda temukan.
Script linker dan kode bootstrap memiliki hubungan yang sangat intim, mereka menikah, bergabung di pinggul, Anda tidak mengembangkan satu tanpa yang lain yang menyebabkan kegagalan besar. Dan sayangnya skrip linker ditentukan oleh linker dan bahasa assembly didefinisikan oleh assembler sehingga Anda mengubah toolchain berharap harus menulis ulang keduanya. Mengapa bahasa assembly? Tidak perlu bootstrap, bahasa yang dikompilasi umumnya dilakukan. C tidak jika Anda tidak ingin membatasi penggunaan langauge, saya akan mulai dengan sesuatu yang sangat sederhana yang memiliki persyaratan spesifik toolchain minimal, Anda tidak menganggap. , cobalah untuk menghindarinya, ini tidak berlaku untuk variabel lokal, jadi Anda harus tahu kapan Anda menggunakannya. jadi mengapa kita berbicara tentang .bs dan .data ??? (global bagus untuk pekerjaan level ini tapi itu topik lain)) aturan lain untuk solusi sederhana adalah jangan menginisialisasi variabel dalam deklarasi, lakukan dalam kode. ya membakar lebih banyak flash, Anda biasanya memiliki banyak, tidak semua variabel diinisialisasi dengan konstanta pula yang akhirnya menghabiskan instruksi.
Anda dapat mengetahui dari desain cortex-m bahwa mereka mungkin berpikir tidak ada kode bootstrap sama sekali sehingga tidak ada .data atau .bss yang mendukung. Kebanyakan orang yang menggunakan global tidak dapat hidup tanpa hal ini:
Saya bisa membuat ini lebih minimal tetapi contoh fungsional minimal untuk semua korteks-ms menggunakan gnu toolchain, saya tidak ingat versi apa yang bisa Anda mulai dengan 5.xx atau lebih hingga 9.xx saat ini. Saya mengganti skrip linker di suatu tempat sekitar 3. xx atau 4.xx ketika saya belajar lebih banyak dan ketika gnu mengubah sesuatu yang merusak yang pertama saya.
bootstrap:
.thumb
.thumb_func
.global _start
_start:
stacktop: .word 0x20000800
.word reset
.word done
.word done
.word done
.thumb_func
reset:
bl centry
b done
.thumb_func
done: b .
.thumb_func
.globl bounce
bounce:
bx lr
titik masuk ke dalam kode C:
void bounce ( unsigned int );
unsigned int a;
int centry ( void )
{
a = 7;
bounce(a);
return(0);
}
skrip tautan.
MEMORY
{
rom : ORIGIN = 0x00000000, LENGTH = 0x1000
ram : ORIGIN = 0x20000000, LENGTH = 0x1000
}
SECTIONS
{
.text : { *(.text*) } > rom
.rodata : { *(.rodata*) } > rom
.bss : { *(.bss*) } > ram
}
Semua ini bisa lebih kecil dan masih berfungsi, menambahkan beberapa hal tambahan di sini hanya untuk melihatnya di tempat kerja.
build dan tautan yang dioptimalkan.
00000000 <_start>:
0: 20001000
4: 00000015
8: 0000001b
c: 0000001b
10: 0000001b
00000014 <reset>:
14: f000 f804 bl 20 <centry>
18: e7ff b.n 1a <done>
0000001a <done>:
1a: e7fe b.n 1a <done>
0000001c <bounce>:
1c: 4770 bx lr
...
00000020 <centry>:
20: 2207 movs r2, #7
22: b510 push {r4, lr}
24: 4b04 ldr r3, [pc, #16] ; (38 <centry+0x18>)
26: 2007 movs r0, #7
28: 601a str r2, [r3, #0]
2a: f7ff fff7 bl 1c <bounce>
2e: 2000 movs r0, #0
30: bc10 pop {r4}
32: bc02 pop {r1}
34: 4708 bx r1
36: 46c0 nop ; (mov r8, r8)
38: 20000000 andcs r0, r0, r0
Disassembly of section .bss:
20000000 <a>:
20000000: 00000000 andeq r0, r0, r0
untuk beberapa vendor Anda ingin menggunakan 0x08000000 atau 0x01000000 atau alamat serupa lainnya saat flash dipetakan di sana dan dicerminkan ke 0x00000000 dalam beberapa mode boot. beberapa hanya memiliki banyak flash yang dicerminkan pada 0x00000000 sehingga Anda ingin memiliki titik tabel vektor pada ruang flash aplikasi bukan nol. karena ini adalah tabel vektor semua bekerja.
Catatan pertama, korteks-ms adalah mesin ibu jari saja dan untuk alasan apa pun mereka menerapkan alamat fungsi ibu jari, yang berarti lsbit aneh. Ketahui alat Anda, arahan .thumb_func memberi tahu assembler gnu bahwa label berikutnya adalah alamat fungsi ibu jari. melakukan hal +1 dalam tabel akan menyebabkan kegagalan, jangan tergoda untuk melakukannya, lakukan dengan benar. ada cara assembler gnu lain untuk menyatakan fungsi ini adalah pendekatan minimal.
4: 00000015
8: 0000001b
c: 0000001b
10: 0000001b
itu tidak akan boot jika Anda tidak mendapatkan tabel vektor dengan benar.
bisa dibilang hanya perlu stack pointer vector (bisa meletakkan apa saja di sana jika Anda ingin mengatur stack pointer sendiri dalam kode) dan reset vektor. Saya menempatkan empat di sini tanpa alasan tertentu. Biasanya menempatkan 16 tetapi ingin mempersingkat contoh ini.
Jadi, apa yang minimal yang perlu dilakukan bootstrap C? 1. mengatur penunjuk tumpukan 2. nol .bss 3. menyalin. Data 4. cabang ke atau memanggil titik entri C
titik masuk C biasanya disebut main (). tetapi beberapa toolchain melihat main () dan menambahkan sampah tambahan ke kode Anda. Saya sengaja menggunakan nama yang berbeda. YMMV.
salinan data tidak diperlukan jika ini semua berbasis ram. menjadi mikrokontroler korteks-m secara teknis dimungkinkan tetapi tidak mungkin sehingga salinan data diperlukan ..... jika ada. data.
Contoh pertama saya dan gaya pengkodean adalah untuk tidak bergantung pada data atau .bss, seperti dalam contoh ini. Arm menangani stack pointer sehingga satu-satunya yang tersisa adalah memanggil titik masuk. Saya suka memilikinya sehingga titik masuk dapat kembali, banyak orang berpendapat Anda tidak boleh melakukan itu. Anda bisa melakukan ini:
.thumb_func
.global _start
_start:
stacktop: .word 0x20000800
.word centry
.word done
.word done
.word done
dan tidak kembali dari centry () dan tidak memiliki kode reset handler.
00000020 <centry>:
20: 2207 movs r2, #7
22: b510 push {r4, lr}
24: 4b04 ldr r3, [pc, #16] ; (38 <centry+0x18>)
26: 2007 movs r0, #7
28: 601a str r2, [r3, #0]
2a: f7ff fff7 bl 1c <bounce>
2e: 2000 movs r0, #0
30: bc10 pop {r4}
32: bc02 pop {r1}
34: 4708 bx r1
36: 46c0 nop ; (mov r8, r8)
38: 20000000 andcs r0, r0, r0
Disassembly of section .bss:
20000000 <a>:
20000000: 00000000
linker telah meletakkan hal-hal di mana kita bertanya Dan secara keseluruhan kami memiliki program yang berfungsi penuh.
Jadi pertama-tama kerjakan skrip tautan:
MEMORY
{
bob : ORIGIN = 0x00000000, LENGTH = 0x1000
ted : ORIGIN = 0x20000000, LENGTH = 0x1000
}
SECTIONS
{
.text : { *(.text*) } > bob
.rodata : { *(.rodata*) } > bob
__data_rom_start__ = .;
.data : {
__data_start__ = .;
*(.data*)
} > ted AT > bob
__data_end__ = .;
__data_size__ = __data_end__ - __data_start__;
.bss : {
__bss_start__ = .;
*(.bss*)
} > ted
__bss_end__ = .;
__bss_size__ = __bss_end__ - __bss_start__;
}
menekankan bahwa nama rom dan ram tidak berarti mereka hanya menghubungkan titik-titik untuk penghubung antar bagian.
.thumb
.thumb_func
.global _start
_start:
stacktop: .word 0x20000800
.word reset
.word done
.word done
.word done
.thumb_func
reset:
bl centry
b done
.thumb_func
done: b .
.thumb_func
.globl bounce
bounce:
bx lr
.align
.word __data_rom_start__
.word __data_start__
.word __data_end__
.word __data_size__
tambahkan beberapa item sehingga kita dapat melihat apa yang dilakukan alat
void bounce ( unsigned int );
unsigned int a;
unsigned int b=4;
unsigned char c=5;
int centry ( void )
{
a = 7;
bounce(a);
return(0);
}
tambahkan beberapa item untuk ditempatkan di bagian tersebut. dan dapatkan
Disassembly of section .text:
00000000 <_start>:
0: 20000800 andcs r0, r0, r0, lsl #16
4: 00000015 andeq r0, r0, r5, lsl r0
8: 0000001b andeq r0, r0, r11, lsl r0
c: 0000001b andeq r0, r0, r11, lsl r0
10: 0000001b andeq r0, r0, r11, lsl r0
00000014 <reset>:
14: f000 f80c bl 30 <centry>
18: e7ff b.n 1a <done>
0000001a <done>:
1a: e7fe b.n 1a <done>
0000001c <bounce>:
1c: 4770 bx lr
1e: 46c0 nop ; (mov r8, r8)
20: 0000004c andeq r0, r0, r12, asr #32
24: 20000000 andcs r0, r0, r0
28: 20000008 andcs r0, r0, r8
2c: 00000008 andeq r0, r0, r8
00000030 <centry>:
30: 2207 movs r2, #7
32: b510 push {r4, lr}
34: 4b04 ldr r3, [pc, #16] ; (48 <centry+0x18>)
36: 2007 movs r0, #7
38: 601a str r2, [r3, #0]
3a: f7ff ffef bl 1c <bounce>
3e: 2000 movs r0, #0
40: bc10 pop {r4}
42: bc02 pop {r1}
44: 4708 bx r1
46: 46c0 nop ; (mov r8, r8)
48: 20000008 andcs r0, r0, r8
Disassembly of section .data:
20000000 <c>:
20000000: 00000005 andeq r0, r0, r5
20000004 <b>:
20000004: 00000004 andeq r0, r0, r4
Disassembly of section .bss:
20000008 <a>:
20000008: 00000000 andeq r0, r0, r0
inilah hal-hal yang kami cari dalam percobaan itu (perhatikan tidak ada alasan untuk benar-benar memuat atau menjalankan kode apa pun ... ketahui alat Anda, pelajari)
1c: 4770 bx lr
1e: 46c0 nop ; (mov r8, r8)
20: 0000004c andeq r0, r0, r12, asr #32
24: 20000000 andcs r0, r0, r0
28: 20000008 andcs r0, r0, r8
2c: 00000008 andeq r0, r0, r8
jadi apa yang kita pelajari di sini adalah bahwa posisi variabel sangat sensitif dalam skrip gnu linker. perhatikan posisi data_rom_start vs data_start tetapi mengapa data_end berfungsi? Aku akan membiarkan kamu mencari tahu itu. Sudah mengerti mengapa orang mungkin tidak mau harus mengacaukan dengan skrip linker dan hanya mendapatkan pemrograman sederhana ...
jadi hal lain yang kami pelajari di sini adalah bahwa linker menyelaraskan data_rom_start bagi kami, kami tidak memerlukan ALIGN (4) di sana. Haruskah kita berasumsi bahwa itu akan selalu berhasil?
Perhatikan juga bahwa padded pada jalan keluar ke, kita memiliki 5 byte. Data tetapi padded ke 8. Tanpa ALIGN () kita sudah bisa melakukan copy menggunakan kata-kata. Berdasarkan apa yang kita lihat dengan rantai alat ini di komputer saya hari ini, mungkinkah itu benar untuk masa lalu dan masa depan? Siapa tahu, bahkan dengan ALIGNs perlu memeriksa secara berkala untuk mengonfirmasi beberapa versi baru yang tidak merusak, mereka akan melakukannya dari waktu ke waktu.
dari percobaan itu mari kita beralih ke ini hanya untuk aman.
MEMORY
{
bob : ORIGIN = 0x00000000, LENGTH = 0x1000
ted : ORIGIN = 0x20000000, LENGTH = 0x1000
}
SECTIONS
{
.text : { *(.text*) } > bob
.rodata : { *(.rodata*) } > bob
. = ALIGN(4);
__data_rom_start__ = .;
.data : {
__data_start__ = .;
*(.data*)
. = ALIGN(4);
__data_end__ = .;
} > ted AT > bob
__data_size__ = __data_end__ - __data_start__;
. = ALIGN(4);
.bss : {
__bss_start__ = .;
*(.bss*)
. = ALIGN(4);
__bss_end__ = .;
} > ted
__bss_size__ = __bss_end__ - __bss_start__;
}
memindahkan ujung ke dalam agar konsisten dengan apa yang dilakukan orang lain. Dan itu tidak mengubahnya:
0000001c <bounce>:
1c: 4770 bx lr
1e: 46c0 nop ; (mov r8, r8)
20: 0000004c andeq r0, r0, r12, asr #32
24: 20000000 andcs r0, r0, r0
28: 20000008 andcs r0, r0, r8
2c: 00000008 andeq r0, r0, r8
satu lagi tes cepat:
.globl bounce
bounce:
nop
bx lr
memberi
0000001c <bounce>:
1c: 46c0 nop ; (mov r8, r8)
1e: 4770 bx lr
20: 0000004c andeq r0, r0, r12, asr #32
24: 20000000 andcs r0, r0, r0
28: 20000008 andcs r0, r0, r8
2c: 00000008 andeq r0, r0, r8
tidak perlu mengisi antara bouncing dan tanda
Ohh, benar, saya ingat sekarang mengapa saya tidak memasukkan _end__ di dalamnya. karena TIDAK BEKERJA.
MEMORY
{
bob : ORIGIN = 0x00000000, LENGTH = 0x1000
ted : ORIGIN = 0x20000000, LENGTH = 0x1000
}
SECTIONS
{
.text : { *(.text*) } > bob
.rodata : { *(.rodata*) } > bob
. = ALIGN(4);
__data_rom_start__ = .;
.data : {
__data_start__ = .;
*(.data*)
} > ted AT > bob
. = ALIGN(4);
__data_end__ = .;
__data_size__ = __data_end__ - __data_start__;
. = ALIGN(4);
.bss : {
__bss_start__ = .;
*(.bss*)
} > ted
. = ALIGN(4);
__bss_end__ = .;
__bss_size__ = __bss_end__ - __bss_start__;
}
beberapa kode sederhana, tetapi sangat portabel untuk menikah dengan skrip linker ini
.thumb
.thumb_func
.global _start
_start:
stacktop: .word 0x20000800
.word reset
.word done
.word done
.word done
.thumb_func
reset:
ldr r0,blen
cmp r0,#0
beq bss_zero_done
ldr r1,bstart
mov r2,#0
bss_zero:
stmia r1!,{r2}
sub r0,#4
bne bss_zero
bss_zero_done:
ldr r0,dlen
cmp r0,#0
beq data_copy_done
ldr r1,rstart
ldr r2,dstart
data_copy:
ldmia r1!,{r3}
stmia r2!,{r3}
sub r0,#4
bne data_copy
data_copy_done:
bl centry
b done
.thumb_func
done: b .
.thumb_func
.globl bounce
bounce:
nop
bx lr
.align
bstart: .word __bss_start__
blen: .word __bss_size__
rstart: .word __data_rom_start__
dstart: .word __data_start__
dlen: .word __data_size__
memberi
Disassembly of section .text:
00000000 <_start>:
0: 20000800 andcs r0, r0, r0, lsl #16
4: 00000015 andeq r0, r0, r5, lsl r0
8: 0000003d andeq r0, r0, sp, lsr r0
c: 0000003d andeq r0, r0, sp, lsr r0
10: 0000003d andeq r0, r0, sp, lsr r0
00000014 <reset>:
14: 480c ldr r0, [pc, #48] ; (48 <blen>)
16: 2800 cmp r0, #0
18: d004 beq.n 24 <bss_zero_done>
1a: 490a ldr r1, [pc, #40] ; (44 <bstart>)
1c: 2200 movs r2, #0
0000001e <bss_zero>:
1e: c104 stmia r1!, {r2}
20: 3804 subs r0, #4
22: d1fc bne.n 1e <bss_zero>
00000024 <bss_zero_done>:
24: 480b ldr r0, [pc, #44] ; (54 <dlen>)
26: 2800 cmp r0, #0
28: d005 beq.n 36 <data_copy_done>
2a: 4908 ldr r1, [pc, #32] ; (4c <rstart>)
2c: 4a08 ldr r2, [pc, #32] ; (50 <dstart>)
0000002e <data_copy>:
2e: c908 ldmia r1!, {r3}
30: c208 stmia r2!, {r3}
32: 3804 subs r0, #4
34: d1fb bne.n 2e <data_copy>
00000036 <data_copy_done>:
36: f000 f80f bl 58 <centry>
3a: e7ff b.n 3c <done>
0000003c <done>:
3c: e7fe b.n 3c <done>
0000003e <bounce>:
3e: 46c0 nop ; (mov r8, r8)
40: 4770 bx lr
42: 46c0 nop ; (mov r8, r8)
00000044 <bstart>:
44: 20000008 andcs r0, r0, r8
00000048 <blen>:
48: 00000004 andeq r0, r0, r4
0000004c <rstart>:
4c: 00000074 andeq r0, r0, r4, ror r0
00000050 <dstart>:
50: 20000000 andcs r0, r0, r0
00000054 <dlen>:
54: 00000008 andeq r0, r0, r8
00000058 <centry>:
58: 2207 movs r2, #7
5a: b510 push {r4, lr}
5c: 4b04 ldr r3, [pc, #16] ; (70 <centry+0x18>)
5e: 2007 movs r0, #7
60: 601a str r2, [r3, #0]
62: f7ff ffec bl 3e <bounce>
66: 2000 movs r0, #0
68: bc10 pop {r4}
6a: bc02 pop {r1}
6c: 4708 bx r1
6e: 46c0 nop ; (mov r8, r8)
70: 20000008 andcs r0, r0, r8
Disassembly of section .data:
20000000 <c>:
20000000: 00000005 andeq r0, r0, r5
20000004 <b>:
20000004: 00000004 andeq r0, r0, r4
Disassembly of section .bss:
20000008 <a>:
20000008: 00000000 andeq r0, r0, r0
kita bisa berhenti di situ atau terus berjalan. Jika kita menginisialisasi dalam urutan yang sama dengan skrip linker tidak apa-apa jika kita masuk ke hal berikutnya karena kita belum sampai di sana. dan stm / ldm hanya diperlukan / diinginkan untuk menggunakan alamat yang selaras kata, jadi jika Anda berubah ke:
ldr r0,blen
cmp r0,#0
beq bss_zero_done
ldr r1,bstart
mov r2,#0
mov r3,#0
mov r4,#0
mov r5,#0
bss_zero:
stmia r1!,{r2,r3,r4,r5}
sub r0,#16
ble bss_zero
bss_zero_done:
dengan bss pertama di skrip linker, dan ya Anda mau ble bukan bls.
Disassembly of section .text:
00000000 <_start>:
0: 20000800 andcs r0, r0, r0, lsl #16
4: 00000015 andeq r0, r0, r5, lsl r0
8: 00000043 andeq r0, r0, r3, asr #32
c: 00000043 andeq r0, r0, r3, asr #32
10: 00000043 andeq r0, r0, r3, asr #32
00000014 <reset>:
14: 480d ldr r0, [pc, #52] ; (4c <blen>)
16: 2800 cmp r0, #0
18: d007 beq.n 2a <bss_zero_done>
1a: 490b ldr r1, [pc, #44] ; (48 <bstart>)
1c: 2200 movs r2, #0
1e: 2300 movs r3, #0
20: 2400 movs r4, #0
22: 2500 movs r5, #0
00000024 <bss_zero>:
24: c13c stmia r1!, {r2, r3, r4, r5}
26: 3804 subs r0, #4
28: ddfc ble.n 24 <bss_zero>
0000002a <bss_zero_done>:
2a: 480b ldr r0, [pc, #44] ; (58 <dlen>)
2c: 2800 cmp r0, #0
2e: d005 beq.n 3c <data_copy_done>
30: 4907 ldr r1, [pc, #28] ; (50 <rstart>)
32: 4a08 ldr r2, [pc, #32] ; (54 <dstart>)
00000034 <data_copy>:
34: c978 ldmia r1!, {r3, r4, r5, r6}
36: c278 stmia r2!, {r3, r4, r5, r6}
38: 3810 subs r0, #16
3a: ddfb ble.n 34 <data_copy>
0000003c <data_copy_done>:
3c: f000 f80e bl 5c <centry>
40: e7ff b.n 42 <done>
00000042 <done>:
42: e7fe b.n 42 <done>
00000044 <bounce>:
44: 46c0 nop ; (mov r8, r8)
46: 4770 bx lr
00000048 <bstart>:
48: 20000000 andcs r0, r0, r0
0000004c <blen>:
4c: 00000004 andeq r0, r0, r4
00000050 <rstart>:
50: 20000004 andcs r0, r0, r4
00000054 <dstart>:
54: 20000004 andcs r0, r0, r4
00000058 <dlen>:
58: 00000008 andeq r0, r0, r8
0000005c <centry>:
5c: 2207 movs r2, #7
5e: b510 push {r4, lr}
60: 4b04 ldr r3, [pc, #16] ; (74 <centry+0x18>)
62: 2007 movs r0, #7
64: 601a str r2, [r3, #0]
66: f7ff ffed bl 44 <bounce>
6a: 2000 movs r0, #0
6c: bc10 pop {r4}
6e: bc02 pop {r1}
70: 4708 bx r1
72: 46c0 nop ; (mov r8, r8)
74: 20000000 andcs r0, r0, r0
Disassembly of section .bss:
20000000 <a>:
20000000: 00000000 andeq r0, r0, r0
Disassembly of section .data:
20000004 <c>:
20000004: 00000005 andeq r0, r0, r5
20000008 <b>:
20000008: 00000004 andeq r0, r0, r4
loop itu akan berjalan lebih cepat. sekarang saya tidak tahu apakah bus ahb bisa lebar 64 bit atau tidak tetapi untuk lengan berukuran penuh Anda ingin menyelaraskan hal-hal ini pada batas 64 bit. empat register ldm / stm pada batas 32 bit tetapi bukan batas 64 bit menjadi tiga transaksi bus terpisah, di mana selaras pada batas 64 bit adalah transaksi tunggal yang menghemat beberapa jam per instruksi.
karena kita melakukan baremetal dan kita sepenuhnya bertanggung jawab untuk semua yang kita dapat katakan katakanlah bss pertama maka data maka jika kita menumpuk melakukan itu maka tumpukan tumbuh dari atas ke bawah, jadi jika kita nol bss dan menumpahkan beberapa selama kita mulai dari tempat yang tepat yang baik-baik saja kita belum menggunakan memori itu. lalu kita salin. data lebih dan dapat tumpah ke tumpukan itu baik-baik saja, tumpukan atau tidak ada banyak ruang untuk tumpukan sehingga kita tidak menginjak siapa pun / apa pun (selama kita memastikan dalam skrip linker kita melakukan itu. jika ada kekhawatiran membuat ALIGN () lebih besar sehingga area kami selalu berada dalam ruang kami untuk pengisian ini.
jadi solusi sederhana saya, ambil atau tinggalkan. selamat datang untuk memperbaiki bug, saya tidak menjalankan ini pada perangkat keras maupun simulator saya ...
MEMORY
{
bob : ORIGIN = 0x00000000, LENGTH = 0x1000
ted : ORIGIN = 0x20000000, LENGTH = 0x1000
}
SECTIONS
{
.text : { *(.text*) } > bob
.rodata : { *(.rodata*) } > bob
. = ALIGN(8);
.bss : {
__bss_start__ = .;
*(.bss*)
} > ted
. = ALIGN(4);
__bss_end__ = .;
__bss_size__ = __bss_end__ - __bss_start__;
. = ALIGN(8);
__data_rom_start__ = .;
.data : {
__data_start__ = .;
*(.data*)
} > ted AT > bob
. = ALIGN(4);
__data_end__ = .;
__data_size__ = __data_end__ - __data_start__;
}
.thumb
.thumb_func
.global _start
_start:
stacktop: .word 0x20000800
.word reset
.word done
.word done
.word done
.thumb_func
reset:
ldr r0,blen
cmp r0,#0
beq bss_zero_done
ldr r1,bstart
mov r2,#0
mov r3,#0
mov r4,#0
mov r5,#0
bss_zero:
stmia r1!,{r2,r3,r4,r5}
sub r0,#16
ble bss_zero
bss_zero_done:
ldr r0,dlen
cmp r0,#0
beq data_copy_done
ldr r1,rstart
ldr r2,dstart
data_copy:
ldmia r1!,{r3,r4,r5,r6}
stmia r2!,{r3,r4,r5,r6}
sub r0,#16
ble data_copy
data_copy_done:
bl centry
b done
.thumb_func
done: b .
.thumb_func
.globl bounce
bounce:
nop
bx lr
.align
bstart: .word __bss_start__
blen: .word __bss_size__
rstart: .word __data_rom_start__
dstart: .word __data_start__
dlen: .word __data_size__
void bounce ( unsigned int );
unsigned int a;
unsigned int b=4;
unsigned char c=5;
int centry ( void )
{
a = 7;
bounce(a);
return(0);
}
arm-none-eabi-as --warn --fatal-warnings flash.s -o flash.o
arm-none-eabi-ld -o hello.elf -T flash.ld flash.o centry.o
arm-none-eabi-objdump -D hello.elf > hello.list
arm-none-eabi-objcopy hello.elf hello.bin -O binary
kumpulkan semuanya dan Anda mendapatkan:
Disassembly of section .text:
00000000 <_start>:
0: 20000800 andcs r0, r0, r0, lsl #16
4: 00000015 andeq r0, r0, r5, lsl r0
8: 00000043 andeq r0, r0, r3, asr #32
c: 00000043 andeq r0, r0, r3, asr #32
10: 00000043 andeq r0, r0, r3, asr #32
00000014 <reset>:
14: 480d ldr r0, [pc, #52] ; (4c <blen>)
16: 2800 cmp r0, #0
18: d007 beq.n 2a <bss_zero_done>
1a: 490b ldr r1, [pc, #44] ; (48 <bstart>)
1c: 2200 movs r2, #0
1e: 2300 movs r3, #0
20: 2400 movs r4, #0
22: 2500 movs r5, #0
00000024 <bss_zero>:
24: c13c stmia r1!, {r2, r3, r4, r5}
26: 3810 subs r0, #16
28: ddfc ble.n 24 <bss_zero>
0000002a <bss_zero_done>:
2a: 480b ldr r0, [pc, #44] ; (58 <dlen>)
2c: 2800 cmp r0, #0
2e: d005 beq.n 3c <data_copy_done>
30: 4907 ldr r1, [pc, #28] ; (50 <rstart>)
32: 4a08 ldr r2, [pc, #32] ; (54 <dstart>)
00000034 <data_copy>:
34: c978 ldmia r1!, {r3, r4, r5, r6}
36: c278 stmia r2!, {r3, r4, r5, r6}
38: 3810 subs r0, #16
3a: ddfb ble.n 34 <data_copy>
0000003c <data_copy_done>:
3c: f000 f80e bl 5c <centry>
40: e7ff b.n 42 <done>
00000042 <done>:
42: e7fe b.n 42 <done>
00000044 <bounce>:
44: 46c0 nop ; (mov r8, r8)
46: 4770 bx lr
00000048 <bstart>:
48: 20000000 andcs r0, r0, r0
0000004c <blen>:
4c: 00000004 andeq r0, r0, r4
00000050 <rstart>:
50: 20000008 andcs r0, r0, r8
00000054 <dstart>:
54: 20000004 andcs r0, r0, r4
00000058 <dlen>:
58: 00000008 andeq r0, r0, r8
0000005c <centry>:
5c: 2207 movs r2, #7
5e: b510 push {r4, lr}
60: 4b04 ldr r3, [pc, #16] ; (74 <centry+0x18>)
62: 2007 movs r0, #7
64: 601a str r2, [r3, #0]
66: f7ff ffed bl 44 <bounce>
6a: 2000 movs r0, #0
6c: bc10 pop {r4}
6e: bc02 pop {r1}
70: 4708 bx r1
72: 46c0 nop ; (mov r8, r8)
74: 20000000 andcs r0, r0, r0
Disassembly of section .bss:
20000000 <a>:
20000000: 00000000 andeq r0, r0, r0
Disassembly of section .data:
20000004 <c>:
20000004: 00000005 andeq r0, r0, r5
20000008 <b>:
20000008: 00000004 andeq r0, r0, r4
perhatikan bahwa ini bekerja dengan arm-none-eabi- dan arm-linux-gnueabi dan varian lainnya karena tidak ada hal jagoan ghee yang digunakan.
Anda akan menemukan ketika Anda melihat-lihat bahwa orang-orang akan menjadi gila dengan hal-hal jagoan ghee di skrip linker mereka, hal-hal besar wastafel dapur. Lebih baik hanya tahu bagaimana melakukannya (atau lebih baik cara menguasai alat sehingga Anda dapat mengontrol apa yang terjadi) daripada mengandalkan barang-barang orang lain dan tidak tahu di mana itu akan rusak karena Anda tidak mengerti dan / atau ingin meneliti Itu.
sebagai aturan umum jangan bootstrap bahasa dengan bahasa yang sama (bootstrap dalam arti ini menjalankan kode tidak mengkompilasi kompiler dengan kompiler yang sama) Anda ingin menggunakan bahasa yang lebih sederhana dengan lebih sedikit bootstrap. Itulah sebabnya C dilakukan dalam perakitan, tidak memiliki persyaratan bootstrap yang baru Anda mulai dari instruksi pertama setelah reset. JAVA, tentu Anda bisa menulis jvm di C dan bootstrap C dengan asm lalu bootstrap JAVA jika Anda mau dengan C tetapi juga menjalankan JAVA di C juga.
Karena kami mengontrol asumsi pada loop salinan ini, mereka secara definisi lebih ketat dan lebih bersih daripada memcpy / memset disetel dengan tangan.
Perhatikan masalah Anda yang lain adalah ini:
unsigned int * bss_start_p = &_BSS_START;
unsigned int * bss_end_p = &_BSS_END;
jika ini denda lokal, tidak ada masalah, jika ini global maka Anda perlu. data diinisialisasi pertama untuk mereka untuk bekerja dan jika Anda mencoba trik itu untuk melakukan. data maka Anda akan gagal. Variabel lokal, baik itu akan berfungsi. jika Anda karena suatu alasan memutuskan untuk membuat penduduk lokal yang statis (global saya suka menyebutnya) maka Anda kembali dalam masalah lagi. Setiap kali Anda melakukan tugas dalam deklarasi meskipun Anda harus memikirkannya, bagaimana itu diterapkan dan apakah itu aman / waras. Setiap kali Anda menganggap suatu variabel adalah nol ketika tidak dideklarasikan, kesepakatan yang sama, jika variabel lokal tidak dianggap nol, jika global maka itu adalah. jika Anda tidak pernah menganggapnya nol maka Anda tidak perlu khawatir.