5.循環(huán)&選擇&指針

[TOC]

if的識(shí)別

葉子函數(shù)未保存x30、x29寄存器;

CMP             W0, W1
B.LE            loc_1000068E0

解釋:
`cmp w0, w1` CMP此處相當(dāng)于做了一次減法,但不影響w0、w1,結(jié)果CPSR寄存器產(chǎn)生影響。
同sub不一樣,`sub w0, w1`,sub影響w0,`w0=w0-w1`。

? CMP 把一個(gè)寄存器的內(nèi)容和另一個(gè)寄存器的內(nèi)容或立即數(shù)進(jìn)行比較。但不存儲(chǔ)結(jié)果,只是正確的更改標(biāo)志。
一般CMP做完判斷后會(huì)進(jìn)行跳轉(zhuǎn),后面通常會(huì)跟上B指令

? 在匯編中B.LE這個(gè)比較的方法和高級(jí)語言中的比價(jià)相反,如:高級(jí)代碼寫大于,在生成的匯編中就是小于等于。

? 關(guān)于B.LE loc_1000068E0是小于等于是跳轉(zhuǎn)到后面的地址處。而BL意思是在跳轉(zhuǎn)前保存LR寄存器后在進(jìn)行跳轉(zhuǎn)。而B就直接進(jìn)行跳轉(zhuǎn)。

? 在if的匯編中有跳轉(zhuǎn)就進(jìn)行跳轉(zhuǎn),跳轉(zhuǎn)后繼續(xù)執(zhí)行后面的代碼。

如下是if_else if_else的匯編代碼:

if_else if_else.png
B.LE            loc_1000068E0
// 小于等于時(shí),跳轉(zhuǎn)到loc_1000068E0

ADRP            X8, #_g@PAGE  
ADD             X8, X8, #_g@PAGEOFF
// 找到g的地址
// int8* x8 = &g;
// 將g的地址存放到x8中

LDR             W9, [SP,#0x10+var_4]
// 取出棧里面的var_4給w9
STR             W9, [X8] 
// 將w9的內(nèi)容寫入到x8所指的地址中。

B               loc_1000068F0 
//直接跳轉(zhuǎn)到loc_1000068F0。

循環(huán)

do-while

do-while.png

break

while_break.png

while

while.png

for

for.png

可以while的就可以用for來還原。

效率比較,可以比匯編代碼,CPU讀取每條指令的速度一樣,所以可以只看匯編代碼量。

for-in:是對(duì)C的擴(kuò)展,需要使用到對(duì)象,所以延后實(shí)驗(yàn);

Switch

待續(xù)

編譯器優(yōu)化

xcode 指令優(yōu)化設(shè)置buildsetting的optimization,

優(yōu)化有5個(gè)分級(jí),debug:None,release:Fastest、Smallest.

沒有用到的局部變量和函數(shù)會(huì)被優(yōu)化掉,前提原則是不損壞源代碼的邏輯、運(yùn)行結(jié)果不受影響。

IDA拿到的是優(yōu)化過的代碼,所以IDA不會(huì)有優(yōu)化過程;

release下設(shè)置成None會(huì)對(duì)代碼指令、包的大小有所影響;

函數(shù)有返回結(jié)果時(shí),編譯器優(yōu)化時(shí)可能將函數(shù)運(yùn)行結(jié)果存起來。

函數(shù)是靜態(tài)的,OC是動(dòng)態(tài)的。函數(shù)在編譯時(shí)知道實(shí)現(xiàn)代碼,可以進(jìn)行運(yùn)算。OC方法的實(shí)現(xiàn)要在運(yùn)行時(shí)在內(nèi)存中進(jìn)行查找;

c函數(shù)時(shí)靜態(tài)固定的,OC的是動(dòng)態(tài)的

因?yàn)镺C是對(duì)象的方法?那么C函數(shù)是編譯階段全部已經(jīng)編譯成機(jī)器碼嗎?那OC在編譯階段方法被編譯成什么樣子;C函數(shù)和OC的方法在寫法形式上都是名稱后面跟具體實(shí)現(xiàn),那么C是否會(huì)和OC一樣生成方法列表和對(duì)應(yīng)的實(shí)現(xiàn)地址?或者說成OC方法在編譯時(shí)都將方法編譯成了機(jī)器碼、另外再生成方法列表,所以在APP加載時(shí)只加載了方法列表,調(diào)用時(shí)去查詢對(duì)應(yīng)的方法具體實(shí)現(xiàn)的地址?

因?yàn)楸簧闪藱C(jī)器碼,所以有種說法:核心代碼最好用C或者用assembly編寫會(huì)比用OC編寫更安全,但是話說回來OC和C都被編譯成了機(jī)器碼,那么就不存在這種說法了吧,或者說這種相對(duì)的更安全是針對(duì)哪個(gè)階段而言嗎?

多線程補(bǔ)充

? CPU的寄存器是通用的,所有程序都可以使用它,線程的切換是由操作系統(tǒng)來做的。線程切換時(shí),當(dāng)前線程會(huì)對(duì)當(dāng)前的寄存器進(jìn)行保護(hù),切換回來的是,再讀取出來放回寄存器。

? 防止資源搶奪時(shí)對(duì)內(nèi)存進(jìn)行的。包括代碼片段、屬性變量等;

? 所以寄存器由操作系統(tǒng)保護(hù),內(nèi)存的加鎖由程序來控制;

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容