歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux編程 >> Linux編程 >> TX2440 裸跑實驗-匯編C語言混編(ADS1.2編譯) 進階(二)

TX2440 裸跑實驗-匯編C語言混編(ADS1.2編譯) 進階(二)

日期:2017/3/1 9:58:17   编辑:Linux編程

一.實驗目的:

理解匯編的編程結構,有助於學習ARM匯編與C語言的調用關系,熟悉堆棧的調用關系.

二.實驗環境:

TX2440平台

三.實驗工具:

ADS1.2 + AXD + JLINK調試

四.實驗步驟:

1.在ads 上建立新工程,增加兩個源文件call_C_func.s 和 func.c

1)call_C_func.s源碼

;我的assembler程序,EastonWoo procedure

area init,code,readonly
import add_8
import main
export assembler_add_4
export assembler_add_5
export assembler_add_8

entry ;一個進程中至少有一個.

start
ldr sp,=0x33ff8000 ;程序有效開始指令地址:0x30000000,,堆棧設在內存裡面,也就是大於0x30000000,注意不要跟代碼區沖突;
;如果設成0x1000,是寫不進棧的,讀出來是0xFFFFFFFF.


;********************一:匯編中調用C語言函數:***************************
stmfd sp!,{r0-r3};start看作子程序,保護好r0-r3 壓棧

;5個實參:優先使用ip,即r0-r3,其中ip.ip作為第5個實參
;6個實參:優先使用ip,lr,即r0-r3,ip,lr.其中ip,lr分別作為第5,6個實參.
;其中lr會在子程序壓棧,出棧.
;7個實參:優先使用ip,lr,和一個保存局部變量的寄存器v1,即r0-r3,ip,lr,v1.其中ip,lr,v1分別作為第5,6,7個實參.
;其中lr,v1會在子程序壓棧,出棧
;8個實參:優先使用ip,lr,和二個保存局部變量的寄存器v1,v2,即r0-r3,ip,lr,v1,v2.其中ip,lr,v1,v2分別作為第5,6,7,8個實參.
;其中lr,v1,v2會在子程序壓棧,出棧
;如此類推...
;15個參數開始就更復雜了.因為所有的局部變量寄存器全用了.4+2+8=14.以後有時間再來研究.

;8個參數例子,調用C函數例子.
mov v2,#8
mov v1,#7
mov lr,#6
mov ip,#5
stmfd sp!,{v1-v2} ;壓棧,先壓8,7,也就釋放了v1,v2寄存器.add_8裡會用到這些寄存器.
stmfd sp!,{ip,lr} ;壓棧,再壓6,5,也就釋放了ip,lr寄存器.add_8裡會用到這些寄存器.
mov r3,#4
mov r2,#3
mov r1,#2
mov r0,#1
bl add_8 ;返回值為r0
add sp,sp,#16 ;出棧.


;********************二:C語言中調用匯編函數:***************************
mov v2,#8 ;8個實參進棧.這裡就不重復敘述了.
mov v1,#7
mov lr,#6
stmfd sp!,{v1-v2} ;壓棧,先壓8,7,也就釋放了v1,v2寄存器.add_8裡會用到這些寄存器.
stmfd sp!,{ip,lr} ;壓棧,再壓6,5,也就釋放了ip,lr寄存器.add_8裡會用到這些寄存器.
mov r3,#4
mov r2,#3
mov r1,#2
mov r0,#1
bl main ;bl已經保存了b over 這個地址到lr.
add sp,sp,#16 ;出棧.

ldmfd sp!,{r0-r3}
b over

assembler_add_4 ;子程序直接使用r0-r3這四個實參.
add r0,r0,r1
add r0,r0,r2
add r0,r0,r3
mov pc,lr

assembler_add_5 ;子程序直接使用r0-r3這四個實參和ip這個第5個實參.
add r0,r0,r1
add r0,r0,r2
add r0,r0,r3
add r0,r0,ip
mov pc,lr

;這個8位的匯編函數相當於之前我們討論的8個參數的被調用C函數的反匯編代碼.
assembler_add_8 ;前4個實參,子程序直接使用r0-r3這四個實參;後4個實參分別由ip,lr,v1-v2都是在棧裡得來.
stmfd sp!,{v1-v2,lr}
add ip,r13,#0x14
ldmia ip,{v1-v2}
ldr ip,[r13,#0xc]
ldr lr,[r13,#0x10]
add r0,r0,r1
add r0,r0,r2
add r0,r0,r3
add r0,r0,ip
add r0,r0,lr
add r0,r0,v1
add r0,r0,v2
ldmfd sp!,{v1-v2,pc}

over
nop ;無用功.為了編譯器不報警
end

Copyright © Linux教程網 All Rights Reserved