① 開頭宣告
② 資料初始化
④函式(入棧、操作、出棧)
③ 被初始化的資料的位址(文字池)
注意:②和③聯絡比較大,但為了讓③處在不會被執行的地方,所以將③放在④之後。
下面的例子是乙個算術運算的彙編與c的對照,首先是c語言
/*檔名:test.c*/
/*說明:算術運算*/
int v1 = 1;
static int v2 = 2;
int main(void)
以下為組合語言的內容(請結合表2-1-2理解本程式):
.file 「test.c」
.global v1 @宣告v1為全域性標籤
.data @ 資料段開始
.align 2 @位址與4的倍數對齊
.type v1, %object @v1標籤代表資料物件
.size v1, 4 @物件v1的長度為4
v1: .word 1 @存放v1的初始值1
.align 2 @位址與4的倍數對齊
.type v2, %object @v2標籤代表資料物件
.size v2, 4 @物件v2的長度為4
v2: .word 2 @存放v2的初始值2
.text @ **段開始
.align 2
.global main @ 宣告main為全域性標籤
.type main, %function @ main標籤代表函式
main:
@ args = 0, pretend = 0, frame = 12
@ frame_needed = 1, uses_anonymous_args = 0
@入棧及開闢存放區域性變數的空間
mov ip, sp @暫時用ip儲存棧指標
stmfd sp!, @ 入棧
sub fp, ip, #4 @ fp指向入棧的第乙個元素(函式幀的開始)
sub sp, ip, #12 @ 在棧上開闢3個整形數的空間,用於存放區域性變數
@給v3,v4賦初值
mov r3, #3
str r3, [fp, #-20] @ 將v3賦值為3
mov r3, #4
str r3, [fp, #-24] @ 將v4賦值為4
@計算表示式v1+v2,將結果放到r1中
ldr r3, .l2 @ 將變數v1的位址載入到r3
ldr r2, .l2+4 @ 將變數v2的位址載入到r2
ldr r1, [r3, #0] @ 將變數v1的值載入到r1
ldr r3, [r2, #0] @ 將變數v2的值載入到r3
add r1, r1, r3 @ v1+v2的結果放到r1中
@計算表示式(v3+v4) ,將結果放到r3中
ldr r2, [fp, #-20] @ 將變數v3的值載入到r2上
ldr r3, [fp, #-24] @ 將變數v4的值載入到r3上
add r3, r2, r3 @ (v1+v2)+(v3+v4)的結果放到r3中
@將(v1+v2)-(v3+v4)的值放到r3中,儲存,返回
rsb r3, r3, r1 @ 將(v1+v2) - (v3+v4)的值放到r3之中
str r3, [fp, #-16] @將結果儲存到vr中
ldr r3, [fp, #-16] @將vr的值載入到r3中
mov r0, r3 @ 將(v1+v2) - (v3+v4)的值放到r0中返回
@出棧sub sp, fp, #12 @ 重設棧指標準備返回
ldmfd sp, @ 返回
.l3:
.align 2
.l2 .word v1 @變數v1的位址,即標號v1【使.l2獲得v1的指標】
.word v2 @變數v2的位址,即標號v2
.size main, .-main @ main函式的大小,當前位置減去main標號處
.ident 「gcc: (gnu) 3.4.4」
這裡有點
4需要注意的:
①
全域性變數都被放在資料段上,
資料段中儲存的其實是變數的初始值
②
未用static
宣告的變數會被宣告為
.global
,表示他可以鏈結到其它檔案。
③
載入全域性變數實際上使用的是
文字池的方法,即將變數位址放在**段中某個不會執行到的位置,使用時先載入變數的位址,然後通過變數的位址得到變數的值。
④
每條彙編指令只能執行乙個簡單的運算,計算的中間結果使用暫存器儲存。如果表示式非常複雜以至於無法用暫存器儲存所有的中間結果,則還會在棧上開闢區域性變數來儲存。【
非靜態的區域性變數都放在棧上
,通過幀指標和偏移量的方式來訪問。
幀指標(
fp)在開始時設好,整個函式執行期間不會該變
(而期間
sp會改變
)。】
c 輸出格式控制與C語言對照
cout 的種種 1 標頭檔案 iostream 就不用說了,重要的是iomanip io 的manipulate 1.整型 輸出進製 預設十進位制 八進位制,十進位制,十六進製制 八進位制.int a cin oct a cout 效果等同 printf o a 十六進製制 cin hex a c...
對照Startup s學習ARM彙編指令(轉 )
1 gbll 偽指令用於定義乙個全域性的邏輯變數,並初始化為。gbll bootloader bootloader setl 2 get 或 include get 偽指令用於將乙個原始檔包含到當前的原始檔中,並將被包含的原始檔在當前位置進行彙編處理。可以使用 include 代替 get。incl...
ARM組合語言
指令stmfd和ldmfd分析 根據atpcs規則,我們一般使用fd full descending 型別的資料棧!所以經常使用的指令就有stmfd和ldmfd,通過arm對於棧操作和批量load store指令定址方式,可以知道指令stmfd和ldmfd的位址計算方法 stmfd指令的定址方式為事...