汇编语言调用c语言ads,ADS1.2 在汇编代码中调用C函数
EDA365歡迎您登錄!
您需要 登錄 才可以下載或查看,沒有帳號?注冊
x
, U) b) }+ U8 \" d/ v( \$ ~??T對于ARM體系來說,不同語言撰寫的函數(shù)之間相互調(diào)用(mix calls)遵循的是 ATPCS(ARM-Thumb Procedure Call Standard),ATPCS主要是定義了函數(shù)呼叫時參數(shù)的傳遞規(guī)則以及如何從函數(shù)返回,關(guān)于ATPCS的詳細(xì)內(nèi)容可以查看ADS1.2 Online Books ——Developer Guide的2.1節(jié)。這篇文檔要講的是 匯編代碼中對C函數(shù)調(diào)用時如何進(jìn)行參數(shù)的傳遞以及如何從C函數(shù)正確返回9 O; |6 z8 ?, g- u
" ?# B! P0 k+ [+ p1 d+ w$ U9 {
不同于x86的參數(shù)傳遞規(guī)則,ATPCS建議函數(shù)的形參不超過4個,如果形參個數(shù)少于或等于4,則形參由R0,R1,R2,R3四個寄存器進(jìn)行傳遞;若形參個數(shù)大于4,大于4的部分必須通過堆棧進(jìn)行傳遞。
" e- U7 W" f3 ?3 o; N
9 _/ R1 ]2 \$ Y# D2 b# c& U$ X我們先討論一下形參個數(shù)為4的情況.
/ u6 P5 t. W( Q- E( I實例1:) p2 U- M; [/ k& F
test_asm_args.asm0 \: b" C7 M7 q& }& l1 \2 @5 M. C
//--------------------------------------------------------------------------------( v??u' l& a3 z* e
IMPORT test_c_args ;聲明test_c_args函數(shù)/ G# A" s& _8 k; C
AREA TEST_ASM, CODE, READONLY
: D& M6 M6 y3 `* t" b? ?? ???EXPORT test_asm_args% g) p- L! c2 J8 m6 ]
test_asm_args( G+ m% Y, s' B# a% E1 V" }
STR lr, [sp, #-4]! ;保存當(dāng)前l(fā)r# |. [1 x# Y??E* h* i( }
ldr r0,=0x10? ?? ? ;參數(shù) 18 h* ^& r, s* j4 Z2 F2 P
ldr r1,=0x20? ?? ???;參數(shù) 2% J% I( |) Z- V* x& i
ldr r2,=0x30? ?? ???;參數(shù) 3* j) R3 H4 `??a. G4 W/ k$ R% y
ldr r3,=0x40? ?? ? ;參數(shù) 4
! @' T: w, i5 ?4 \? ?? ???bl test_c_args? ?? ?;調(diào)用C函數(shù)- [. P( O& r. [1 f; K( @
LDR pc, [sp], #4??;將lr裝進(jìn)pc(返回main函數(shù)) 8 L/ C" U% g: s
END% ~0 |2 C, L" f" b! O0 Z% n9 P
test_c_args.c
1 a??A5 z" `# U& b) M" M//--------------------------------------------------------------------------------( d1 F??X4 \- S" h) h# R3 ]& o- [5 C
void test_c_args(int a,int b,int c,int d)
' u- j* f+ d* p6 d{& \2 Z- F- B1 u% w
printk("test_c_args:/n");
" `1 R9 K9 M5 V' s1 z, e? ?? ???printk("%0x %0x %0x %0x/n",a,b,c,d);7 D4 ~4 `3 r- d, j
}4 W! t2 ^2 Q, q' z: y: ]8 A
main.c
9 d& n/ K+ Z! q" P??o//--------------------------------------------------------------------------------
1 h& J: a4 N2 _$ q7 f! [0 eint main()
3 O( `# U% E7 u2 [4 q3 U( V. L{
* `4 O5 |/ f! C5 L2 I3 b? ???test_asm_args();
6 |) E1 c3 N7 Q9 g? ???for(;;);" I( g$ W5 O. \0 t
}
" p1 ]; C, L; {3 l0 ^
4 g7 x4 X' O??J程序從main函數(shù)開始執(zhí)行,main調(diào)用了test_asm_args,test_asm_args調(diào)用了test_c_args,最后從test_asm_args返回main." ^1 {5 `' [0 O8 h' q
代碼分別使用了匯編和C定義了兩個函數(shù),test_asm_args 和 test_c_args,test_asm_args調(diào)用了test_c_args,其參數(shù)的傳遞方式就是向R0~R3分別寫入?yún)?shù)值,之后使用bl語句對test_c_args進(jìn)行調(diào)用。其中值得注意的地方是用紅色標(biāo)記的語句,test_asm_args在調(diào)用test_c_args之前必須把當(dāng)前的lr入棧,調(diào)用完test_c_args之后再把剛才保存在棧中的lr寫回pc,這樣才能返回到main函數(shù)中。% }6 \( Z$ L# g, ^
8 o" T" f" T7 e* d3 U" x, K; a+ m5 j, L/ c; K/ t; f2 d0 ?
如果test_c_args的參數(shù)是8個呢?這種情況test_asm_args應(yīng)該怎樣傳遞參數(shù)呢?' F0 J" v0 F$ a7 n2 S
實例2:
, q; h! b, v+ ktest_asm_args.asm
7 B# `8 B6 K0 j; n4 Q//--------------------------------------------------------------------------------3 d0 C( `9 q' o% T
IMPORT test_c_args ;聲明test_c_args函數(shù)
! [, @$ A3 B+ X/ W& K" P? ?? ???AREA TEST_ASM, CODE, READONLY
. K# I/ x# v# r& o( S? ?? ???EXPORT test_asm_args
- ?/ Q7 ^??r: q+ k5 h7 ptest_asm_args+ C% V% E) W/ D8 K; J8 I
STR lr, [sp, #-4]! ;保存當(dāng)前l(fā)r- J, Y, s. x9 D0 L
ldr r0,=0x1 ;參數(shù) 14 D, e/ @$ w' o, Y3 b6 O
ldr r1,=0x2 ;參數(shù) 2
0 p4 B9 A) z1 R" d? ?? ? ldr r2,=0x3 ;參數(shù) 3
7 [( l5 `( J- e" j- R; O; g# {? ?? ? ldr r3,=0x4 ;參數(shù) 4
: E5 T; d( l- ?9 T, n5 G6 T, X? ?? ? ldr r4,=0x8
! p% y% v# l: v? ?? ? str r4,[sp,#-4]! ;參數(shù) 8 入棧. Z% l# H; h) w1 Z, J" r% M; b: K
ldr r4,=0x7~+ K& N2 w1 y1 b# \
str r4,[sp,#-4]! ;參數(shù) 7 入棧% G( Q: ^+ y7 [( t1 J0 \1 s1 d; O
ldr r4,=0x6: X" c) A- c: B??M. j) u
str r4,[sp,#-4]! ;參數(shù) 6 入棧
& y1 G* g$ u. e) a) x? ?? ? ldr r4,=0x5* H5 m4 L* N$ c
str r4,[sp,#-4]! ;參數(shù) 5 入棧, V* R/ v8 W$ G2 h, [' F- M$ `" ^
bl test_c_args_lots
8 i% t8 `0 Y! z& B9 F4 u0 h' e& Q? ?? ? ADD sp, sp, #4? ???;清除棧中參數(shù) 5,本語句執(zhí)行完后sp指向 參數(shù)6 # V0 D" b" d- {5 k1 V
ADD sp, sp, #4? ???;清除棧中參數(shù) 6,本語句執(zhí)行完后sp指向 參數(shù)75 q. l4 Y0 ^/ v+ }" ~* ^4 P, {' i
ADD sp, sp, #4? ???;清除棧中參數(shù) 7,本語句執(zhí)行完后sp指向 參數(shù)8
0 `8 U+ |' d2 ?; F1 S- X? ?? ? ADD sp, sp, #4? ???;清除棧中參數(shù) 8,本語句執(zhí)行完后sp指向 lr. _* ?! A8 ^* l
LDR pc, [sp],#4? ? ;將lr裝進(jìn)pc(返回main函數(shù)) % I6 f" K( y( R" h$ J( j
END, e9 |5 @/ r??e! D' }6 b$ Y
test_c_args.c
7 [??x9 D/ J1 p3 w: R) L& ?! S! O8 g& {//--------------------------------------------------------------------------------
3 H: y' V2 C6 j' A" P& ^void test_c_args(int a,int b,int c,int d,int e,int f,int g,int h)
& C" M5 p5 t, k- Z3 a6 L0 ?{0 X; v7 n" }5 M" O
printk("test_c_args_lots:/n");. |( @9 P, v# D. A# ^* k* k
printk("%0x %0x %0x %0x %0x %0x %0x %0x/n",/ L8 d. I??D& Z+ p$ i4 ]
a,b,c,d,e,f,g,h);
" A$ u4 T! _+ f??[( c}! b1 v! [6 F6 K" P. t
main.c! B8 N3 p5 [6 a$ J
//--------------------------------------------------------------------------------
& S# I1 z" F8 Q+ x+ @5 }9 y4 `- \int main()
: D4 U" k4 `/ P7 c! f{
# l! }4 b! r6 S1 r8 _( e- \??H? ???test_asm_args();
3 ~0 A3 R6 V- d- x' p? ???for(;;);, B' T, [??p& U* o& {
}' Z3 n: z) u. Y& @
) G4 d9 Z. Z% s% h" H??B
這部分的代碼和實例1的代碼大部分是相同的,不同的地方是test_c_args的參數(shù)個數(shù)和test_asm_args的參數(shù)傳遞方式。
5 g& H+ x& z- m在test_asm_args中,參數(shù)1~參數(shù)4還是通過R0~R3進(jìn)行傳遞,而參數(shù)5~參數(shù)8則是通過把其壓入堆棧的方式進(jìn)行傳遞,不過要注意這四個入棧參數(shù)的入棧順序,是以參數(shù)8->參數(shù)7->參數(shù)6->參數(shù)5的順序入棧的。
) K, g+ ~7 F, p; @1 A直到調(diào)用test_c_args之前,堆棧內(nèi)容如下:% f9 f3 x% m8 M8 b: ~
sp->+----------+
% W" N6 S5 \* c: p$ Q? ?? ???|??參數(shù)5??|0 V8 H8 r! _) |+ x2 Z- N
+----------+
/ b0 E* ?; U( ?: e? ?? ???|??參數(shù)6??|; p! g??J& O% }, j
+----------+, U3 k# ^& ~2 F: R! {??Z
|??參數(shù)7??|$ `1 D+ Q2 j2 n- W: u
+----------+
( m6 i; E1 j* D! Q* `& v? ?? ???|??參數(shù)8??|+ c/ `, [& E# j6 ^
+----------+
& d5 P' Q" F" R??w7 A, \2 @? ?? ???|? ???lr? ?? ?|+ R8 b??T+ _" G
+----------+
- o" S. J; @4 O1 W6 I& O??I/ F- Ntest_c_args執(zhí)行返回后,則設(shè)置sp,對之前入棧的參數(shù)進(jìn)行清除,最后將lr裝入pc返回main函數(shù),在執(zhí)行 LDR pc, [sp],#4 指令之前堆棧內(nèi)容如下:) g$ w& @3 y$ r- ~
+----------+7 K. S, b& |. k; m$ ?
|??參數(shù)5??|
# v+ M' x: m' m$ E2 x8 ]. `? ?? ? +----------+
, J- D% E* q9 k? ?? ???|??參數(shù)6??|
4 a! a7 x7 w2 `. Y1 t; f: N& @? ?? ? +----------+0 R! M??Z, Q??d
|??參數(shù)7??|
" A??t( \5 J+ ]+ |1 R. @? ?? ? +----------+- N: M4 H2 \1 n- K( X! C: |" Z1 t
|??參數(shù)8??|9 O! S/ I! W: j% n+ \" D. }
sp->+----------+% |! B3 Z) I5 ~: o2 d
|? ???lr? ?? ?|* r1 q9 Q- V7 P, H
+----------+
總結(jié)
以上是生活随笔為你收集整理的汇编语言调用c语言ads,ADS1.2 在汇编代码中调用C函数的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: cad图层管理插件_设计大神CAD常用七
- 下一篇: c语言大数倍数,leetcode-134