日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

汇编语言调用c语言ads,ADS1.2 在汇编代码中调用C函数

發(fā)布時間:2025/3/15 编程问答 13 豆豆
生活随笔 收集整理的這篇文章主要介紹了 汇编语言调用c语言ads,ADS1.2 在汇编代码中调用C函数 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

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)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 亚洲视频中文 | 暴力调教一区二区三区 | 中文字幕乱码人妻无码久久95 | 精品国产乱码久久久久久蜜柚 | 金瓶风月在线 | 午夜激情综合网 | 奇米影视777四色 | 熟女人妇 成熟妇女系列视频 | 国产精品一区二区三区免费视频 | 丰满的人妻hd高清日本 | а√中文在线资源库 | 中文字幕日韩人妻在线视频 | 日本乱大交xxxx公交车 | 91视频三区 | 亚洲666| 久久久久久久影视 | 欧美一级性视频 | 欧美天堂在线视频 | 成年人小视频 | 免费一区二区 | 中文在线最新版天堂 | 天天色天天射综合网 | 午夜视频免费观看 | 亚洲成人免费电影 | 国产精品日本一区二区在线播放 | 国产精品果冻传媒 | 成人午夜又粗又硬又大 | 久久精热| 亚洲日本片| 久久久久亚洲av成人无码电影 | 免费观看av的网站 | 富二代成人短视频 | 国产又大又粗又硬 | 福利视频不卡 | 亚洲色图网站 | 日韩精品中文字幕一区 | 91丝袜视频 | 亚洲欧美黄色片 | 日韩aⅴ在线观看 | 亚洲中午字幕 | 一本之道高清无码视频 | 国产一二三四五区 | 中文在线字幕 | 麻豆影视| 一级女性全黄久久生活片免费 | 姐姐你真棒插曲快来救救我电影 | 综合热久久 | 欧美成人免费大片 | 久一精品| 99久久久无码国产 | 天天做天天爱天天做 | 成人免费视频一区二区三区 | 成人永久免费视频 | 欧美亚洲国产一区二区三区 | 亚洲制服无码 | 亚洲一线在线观看 | 无码人妻精品一区二区三区9厂 | 亚洲免费一区视频 | 三年在线观看视频 | 国产av无码国产av毛片 | 亚洲一区不卡 | 女生喷水视频 | 日本免费在线观看视频 | 久久成人a毛片免费观看网站 | 国产精品无码免费播放 | 国产精品人人做人人爽 | 香蕉国产在线 | 欧美三个黑人玩3p | 国产一区不卡视频 | 国产伦精品一区二区三区照片 | 伊人网在线免费观看 | 亚欧洲精品视频 | 国产精品免费看 | 国产欧美日韩成人 | 国产黑丝精品 | 久久免费看少妇高潮 | 亚洲永久免费 | 九九视频免费观看 | 亚洲福利天堂 | 亚洲欧美一区二区在线观看 | 九一福利视频 | 亚洲视频 一区 | 日韩视频在线观看 | 我们的2018中文免费看 | 热逼视频 | 91国产视频在线观看 | 一区二区三区爱爱 | 国产超碰人人 | 成人a免费| 欧美日一区二区 | 天天干天天干天天干天天 | 亚洲精品久久久中文字幕痴女 | 中文字幕一区二区三区四区五区 | 亚洲午夜av在线 | 久久精彩免费视频 | 国产精品亚洲色图 | 国产区精品在线观看 | 亚洲天堂精品在线观看 | 亚洲精品少妇一区二区 |