我的第一個ARM彙編程序(霓虹燈~~~)

開始基於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文件格式差不了太多。
在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章