開始基於S3C2440學習ARM裸機,記錄一下第一個ARM彙編程序(比起8086的指令,ARM的指令要難一些,當然ARM指令比起IA32也是稍有遜色,畢竟越是技術更新換代,所需功能越多,複雜度也就越大)
@
@ Time:2019年4月1日23:15:07
@ Author:Apollon_krj
@ 所有的三個LED點燈(GPF4~GPF6):1爲滅,0爲亮
@ 流水燈
@
@ arm的函數調用與返回,與8086差別還是蠻大的
@ (主要是當前不知道有什麼比較類似於x86的call、ret指令,以下指令也是爲了一個目的而去搜的)
@ 後者用stack存放函數地址,前者則直接是lr和pc兩個寄存器來搞
@ 8086更趨向與軟件邏輯,是兩步:先call,再ret
@ 而arm則更隨心所欲一些,是三步:先保存返回地址,再修改pc指針,執行完恢復pc指針
@ 即call指令相當於“LDR lr, =label_ret”、“LDR lr,=label_call”兩條指令
@ 而ret指令相當於“MOV pc,lr”一條指令,也即8086“MOV pc,ss:[sp]”
@ 注意:ARM中,pc寄存器的值,永遠是當前執行指令地址+8,而不是當前指令地址
@ 因爲:當前執行指令地址爲A,A+4指令已經開始被解析,而A+8指令已經開始被讀取(即PC)
@
.text
.global _start
_start:
LDR r0, =0x00 @ 0000 0000,亮亮亮
LDR lr, =one_light_delay @ 點燈完成後的地址,即返回地址
LDR pc, =_led_light @ 點燈指令起始地址,等價於 B _led_light
one_light_delay:
LDR lr, =two_light @ 延時完成後的指令地址
B _delay @ 延時指令起始地址
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
two_light:
LDR r0, =0x70 @ 0111 0000,滅滅滅
LDR lr, =two_light_delay
B _led_light
two_light_delay:
LDR lr, =_start @ 死循環
B _delay
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
_led_light:
LDR r1, =0x56000050
LDR r2, =0x1500 @ choose GPF:0001 0101 0000 0000,選中三個GPIO的輸入功能
LDR r3, [r1] @ 獲取原來的設置
ORR r2, r3 @ 將新配置(GPF4~GPF6 output)增加上去
STR r2, [r1]
LDR r1, =0x56000054
MOV r2, r0 @ set bit:r0
STR r2, [r1]
MOV pc, lr @ 回複函數返回地址,接着執行
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
_delay:
LDR r3, =0x100 @ 延時256 * 256 = 65536個指令週期
loop_ext:
LDR r4, =0x100
loop_int:
sub r4, r4, #1
cmp r4, #0
BNE loop_int @ 內層循環條件判斷
sub r3, r3, #1
cmp r3, #0
BNE loop_ext @ 外層循環條件判斷
MOV pc, lr @ 循環結束,返回執行
Makefile:
#FILENAME=light_led
FILENAME=light_led_all
all:
#預處理和編譯
arm-linux-gcc -c -o ${FILENAME}.o ${FILENAME}.S
#鏈接生成帶代碼段、符號表、ELF文件標識等信息的ELF文件
arm-linux-ld -Ttext 0 ${FILENAME}.o -o ${FILENAME}.elf
#由目標代碼生成機器碼的bin文件
arm-linux-objcopy -O binary -S ${FILENAME}.elf ${FILENAME}.bin
#由目標代碼反彙編得出標準彙編指令(非僞彙編指令)
arm-linux-objdump -D ${FILENAME}.elf > ${FILENAME}.dis
clean:
rm *.bin *.elf *.o
查看一下elf文件部分內容和bin文件的機器碼:
可以看出,elf文件的組織形式,有一部分連續的地址存放代碼,文件末尾前一部分地址存放符號表,雖然沒有看多ELF文件的具體組織形式,但是也和PE文件格式差不了太多。