答:可以。因為所謂的bin檔案就是ELF檔案的.text程式碼段。
當然前提是下載工具能識別ELF檔案格式,STM32下載ELF檔案並不意味著STM32可以把ELF download到Flash上,而是下載工具能從ELF提取到bin檔案,下載時通訊鏈路上傳輸的也只有要bin檔案。
例如有elf檔案:
$ arm-none-eabi-objdump.exe -s main2.elf main2.elf: file format elf32-littlearm Contents of section .text: 8000000 00100020 09000008 01488546 fee70000 ... .....H.F.... 8000010 00100020 ... Contents of section .ARM.attributes: 0000 41200000 00616561 62690001 16000000 A ...aeabi...... 0010 05436f72 7465782d 4d340006 0d074d09 .Cortex-M4....M. 0020 02
arm-none-eabi-objcopy -O binary main2.elf main2.bin, 它生成bin檔案為:
address 00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 AscII 00000000 00 10 00 20 09 00 00 08 01 48 85 46 fe e7 00 00 ... .....H.F.... 00000010 00 10 00 20 ...
使用STM32 cube programmer直接開啟elf檔案不僅可以預覽,還能直接下載ELF檔案,看到的資料和上面使用objump生成的bin檔案一樣的。
在cube programmer裡連下載地址都不用設定,若開啟的是bin檔案,無論Segger J-Flash還是cube programmer,都是需要手動設定Flash下載地址的。
答:10位元組。
0x00地址:MSP值。
0X04地址:reset handler地址,值為0x08
0x08地址:BL . (死迴圈,thumb指令2位元組)
下面的組合程式碼中0x04地址為PC初始值: 09 00 00 08,小端格式實際值為0x08000009,為何是奇數?
答:cortex MCU不可能產生奇數指令,ARM模式4位元組對齊低2位是0,Thumb模式2位元組對齊低1位是0,所以PC最低位就屬於空閒的,而Cortex MCU需要識別當前是ARM模式還是Thumb模式,所以使用PC最低位就能識別這兩種模式。
R15是程式計數器,在組合程式碼中用PC表示,ARM規定PC最低位LSB用於表示是ARM指令(0)還是Thumb指令(1)。
設計程式碼,直接寫組合
.syntax unified .cpu cortex-m4 .fpu softvfp .thumb // Global memory locations. .global vtable .global reset_handler // The actual vector table. .type vtable, %object vtable: .word _estack .word reset_handler .size vtable, .-vtable /* * The Reset handler. Called on reset. */ .type reset_handler, %function reset_handler: // Set the stack pointer to the end of the stack. //LDR r0, =_estack //MOV sp, r0 //MOVS r0, #0 main_loop: //ADDS r0, r0, #1 B main_loop .size reset_handler, .-reset_handler
編譯生成二進位制檔案
$ arm-none-eabi-objdump.exe -d main2.elf main2.elf: file format elf32-littlearm Disassembly of section .text: 08000000 <vtable>: 8000000: 00 10 00 20 09 00 00 08 ... .... 08000008 <reset_handler>: 8000008: e7fe b.n 8000008 <reset_handler>
這並不是一個理論demo,而是一個可以執行的程式。
第一步下載:
第二步,執行,由於這個程式沒有任何有效的命令,所以無論如何單步都看不到變化,只能看到SP和PC指標已經正確的load了。
簡單修改,加一個暫存器做累加計算方便看到效果,每點一次單步暫存器值加1,程式碼由10位元組變為了14位元組。
$ arm-none-eabi-objdump.exe -d main2.elf main2.elf: file format elf32-littlearm Disassembly of section .text: 08000000 <vtable>: 8000000: 00 10 00 20 09 00 00 08 ... .... 08000008 <reset_handler>: 8000008: 2000 movs r0, #0 0800000a <main_loop>: 800000a: 3001 adds r0, #1 800000c: e7fd b.n 800000a <main_loop>
第一步:下載
第二步:復位,執行指令
8000000: 00 10 00 20 09 00 00 08
8000008: 2000 movs r0, #0
單步:執行指令 ,累加和迴圈
0800000a <main_loop>:
800000a: 3001 adds r0, #1
800000c: e7fd b.n 800000a <main_loop>
單步:
單步:
單步
單步:
直接全速run後暫停: