/** 代碼演示 - les.s **/.text.global _start.code 32@ 定義三個(gè)控制led燈的GPIO寄存器.equ GPIOC_OUT, 0xc001c000.equ GPIOC_OUTENB, 0xc001c004.equ GPIOC_ALTFN0, 0xc001c020_start: @ 功能選擇 FUNCTION1 ldr r0, =GPIOC_ALTFN0 @ r0=0xc001c020 ldr r1, [r0] @ r0放到r1作為緩存 mov r2, #0x03 bic r1, r1, r2, lsl #24 @ clear r1 [25:24] mov r2, #1 orr r1, r1, r2, lsl #24 @ set r1 [24] str r1, [r0] @ 寫回r0寄存器GPIOC_ALFN0 @ 配置為輸出功能 ldr r0, =GPIOC_OUTENB @ r0=0xc001c004 ldr r1, [r0] mov r2, #1 orr r1, r1, r2, lsl #12 @ set r1 [12] str r1, [r0] @ 寫回r0寄存器GPIOC_OUTENB mov r2, #1loop: @ 亮燈 ldr r0, =GPIOC_OUT @ r0=0xc001c000 ldr r1, [r0] bic r1, r1, r2, lsl #12 @ clear r1 [12] str r1, [r0] bl delay @ 調(diào)用函數(shù)delay @ 滅燈 ldr r0, =GPIOC_OUT @ r0=0xc001c000 ldr r1, [r0] orr r1, r1, r2, lsl #12 @ set r1 [12] str r1, [r0] bl delay b loop @ b跳轉(zhuǎn)loop循環(huán) - led間歇閃爍delay: mov r0, #0x8000000 @ 設(shè)置延時(shí),值較C語(yǔ)言大,因速度快delay_loop: sub r0, r0, #1 @ r0=r0-1 cmp r0, #0 @ 比較 r0 與 0 bne delay_loop @ 不相等,b跳轉(zhuǎn)自身循環(huán)繼續(xù)-- mov pc, lr @ bx lr 壓棧.end/** ------------------------------------------------------- **/4、C和匯編的混合調(diào)用 ATPCS // ARM體系結(jié)構(gòu)與編程.pdf --->P241. 1)使用的滿減棧 FD 2)函數(shù)參數(shù)的傳遞,前4個(gè)參數(shù)使用 r0 r1 r2 r3剩余參數(shù)使用棧傳遞 3)函數(shù)返回時(shí),返回值使用r04.1 匯編中如何調(diào)用C函數(shù) xxx.s - 匯編 .extern func @// 使用extern聲明func標(biāo)號(hào)為外部函數(shù) mov r0, #5 @// r0 里面最終會(huì)保存函數(shù)的返回值 mov r1, #10 bl func @// bl 調(diào)用func函數(shù),傳遞參數(shù)5和10 yyy.c - C程序 int func (int a, int b) { return a + b; }4.2 C程序中如何調(diào)用匯編函數(shù) yyy.c - C程序 extern int func (int, int); func (10, 20); xxx.s - 匯編 .global func @// 必要條件 func: add r0, r0, r1 mov pc, lr4.3 C程序中嵌套匯編語(yǔ)法練習(xí): shell框架程序。 使用匯編實(shí)現(xiàn)led.c里面的函數(shù) - led.s。' vi Makefile 新增arm的as編譯匯編文件變量 AS=arm-cortex_a9-linux-gnueabi-as %.o:%.s $(AS) $< -o $@/** 代碼演示 **/.text.global led_init.global led_on.global led_off.code 32.extern uart_puts @// 打印字符換來(lái)做調(diào)試使用.equ GPIOC_OUT, 0xc001c000.equ GPIOC_OUTENB, 0xc001c004.equ GPIOC_ALTFN0, 0xc001c020led_init: stmfd sp!, {lr} @// 把lr壓棧,保證lr是原來(lái)的值 ldr r0, =str1 @// 將str1的首地址放到r0里面 bl uart_puts @// 調(diào)用uart_puts函數(shù)來(lái)打印顯示 @ 功能選擇 FUNCITON1 ldr r0, =GPIOC_ALTFN0 @ r0=0xc001c020 ldr r1, [r0] mov r2, #0x03 bic r1, r1, r2, lsl #24 @ clear r1 [25:24] mov r2, #1 orr r1, r1, r2, lsl #24 @ set r1 [24] str r1, [r0] @ 配置為輸出功能 ldr r0, =GPIOC_OUTENB @ r0=0xc001c004 ldr r1, [r0] mov r2, #1 orr r1, r1, r2, lsl #12 @ set r1 [12] str r1, [r0] mov pc, lr @ 壓棧,相當(dāng)于函數(shù)返回return @// ldmfd sp!, {lr} 打印調(diào)試信息,使用此句彈棧led_on: mov r2, #1 @ 把1放在r2寄存器緩沖區(qū) ldr r0, =GPIOC_OUT @ r0=0xc001c000 ldr r1, [r0] bic r1, r1, r2, lsl #12 @ clear r1 [12] - 低電平 - 亮 str r1, [r0] mov pc, lrled_off: mov r2, #1 ldr r0, =GPIOC_OUT ldr r1, [r0] orr r1, r1, r2, lsl #12 @ set r1 [12] - 高電平 - 亮 str r1, [r0] mov pc, lrstr1: .string "/nled_init/0".end/** ------------------------------------------------------- **/練習(xí)二: 使用匯編指令將strcmp.c替換為strcmp.s的匯編文件。/** 代碼演示 - strcmp.s **/.text.code 32.global my_strcmpmy_strcmp:cmp_loop: ldrb r2, [r0], #1 @ // 每次取1個(gè)字符出來(lái)放到r2寄存器 ldrb r3, [r1], #1 @ // 每次取1個(gè)字符出來(lái)放到r3寄存器 cmp r2, #0 @ // 判斷r2是否到末尾 beq cmp_end @ // 如果r2==0到末尾,就跳轉(zhuǎn)到cmp_end cmp r2, r3 @ // beq cmp_loopcmp_end: sub r0, r2, r3 mov pc, lr @ // <==> bx lr.end/** ------------------------------------------------------- **/<tips>$:' cd 01/$:'ctags -R *$:' vi main.c // 打開(kāi)最開(kāi)始的一個(gè)文件' 光標(biāo)移動(dòng)到函數(shù)或者變量名字上'Ctrl + ] 跳轉(zhuǎn)到定義/實(shí)現(xiàn)位置'Ctrl + t 返回上次跳轉(zhuǎn)之前的位置
新聞熱點(diǎn)
疑難解答
圖片精選
網(wǎng)友關(guān)注