寫個最簡單的helloword.c方法消别,使用clang
命令編譯
#include <stdio.h>
int main() {
printf("hellow word\n");
return 0;
}
使用clang -S -arch arm64 -isysroot
xcrun --sdk iphoneos --show-sdk-pathhelloword.c
杂拨, 其中xcrun --sdk iphoneos --show-sdk-path
輸出響應版本sdk
的目錄
.section __TEXT,__text,regular,pure_instructions
.build_version ios, 13, 4 sdk_version 13, 4
.globl _main ; -- Begin function main
.p2align 2
_main: ; @main
.cfi_startproc
; %bb.0:
sub sp, sp, #32 ; =32
stp x29, x30, [sp, #16] ; 16-byte Folded Spill
add x29, sp, #16 ; =16
.cfi_def_cfa w29, 16
.cfi_offset w30, -8
.cfi_offset w29, -16
stur wzr, [x29, #-4]
adrp x0, l_.str@PAGE
add x0, x0, l_.str@PAGEOFF
bl _printf
mov w8, #0
str w0, [sp, #8] ; 4-byte Folded Spill
mov x0, x8
ldp x29, x30, [sp, #16] ; 16-byte Folded Reload
add sp, sp, #32 ; =32
ret
.cfi_endproc
; -- End function
.section __TEXT,__cstring,cstring_literals
l_.str: ; @.str
.asciz "hellow word\n"
.subsections_via_symbols
代碼中類似.section或.globl等以'.'開頭的, 被稱之為編譯器指令
類似_main:
或l_.str:
被稱之為標簽(label), 用于輔助定位代碼或者資源地址
類似pushq或movq的, 被稱之為匯編指令, 它們會被匯編器編譯為機器代碼, 最終被cpu所執(zhí)行
基本匯編知識
寄存器
寄存器是CPU中的高速存儲單元脊串,要比內(nèi)存中存取要快的多。
r0~r30
r0 - r30
是31個通用整形寄存器抒倚。每個寄存器可以存取一個64位大小的數(shù)。 當使用 x0 - x30
訪問時,它就是一個64位的數(shù)口糕。當使用w0 - w30
訪問時,訪問的是這些寄存器的低32位
其中
r29
又被叫做 fp
(frame pointer
). r30
又被叫做 lr
(link register
)
SP
SP
寄存器其實就是 x31
磕蛇,在指令編碼中景描,使用 SP/WSP
來進行對SP
寄存器的訪問
V0 – V31
V0 - V31
是向量寄存器,也可以說是浮點型寄存器秀撇。它的特點是每個寄存器的大小是 128 位的超棺。 分別可以用Bn Hn Sn Dn Qn
的方式來訪問不同的位數(shù)。如圖
SPRs
SPRs是狀態(tài)寄存器呵燕,用于存放程序運行中一些狀態(tài)標識棠绘。不同于編程語言里面的if else.在匯編中就需要根據(jù)狀態(tài)寄存器中的一些狀態(tài)來控制分支的執(zhí)行。狀態(tài)寄存器又分為 The Current Program Status Register (CPSR)
和 The Saved Program Status Registers (SPSRs)
。 一般都是使用CPSR
弄唧, 當發(fā)生異常時适肠, CPSR
會存入SPSR
。當異澈蛞恢復侯养,再拷貝回CPSR
。
還有一些系統(tǒng)寄存器澄干,還有 FPSR FPCR
是浮點型運算時的狀態(tài)寄存器等逛揩。基本了解上面這些寄存器就可以了
棧
棧就是指令執(zhí)行時存放臨時變量的內(nèi)存空間麸俘。在學習匯編代碼的執(zhí)行過程中辩稽,了解棧的結構非常重要。
先列出一些棧的特性:
- 棧是從高地址到低地址的从媚, 棧低是高地址逞泄,棧頂是低地址。
- fp指向當前frame的棧底拜效,也就是高地址喷众。
-
sp指向棧頂,也就是地地址紧憾。
下面的圖簡單的描述了從方法A調(diào)用方法B時 棧是如何劃分的:
3.jpeg