條件碼旭绒,每個條件碼是單個bit。
CF:進(jìn)位標(biāo)志焦人。最近的操作使最高位產(chǎn)生了進(jìn)位挥吵。
ZF:零標(biāo)志。最近的操作得到的結(jié)果為0
SF:符號標(biāo)志花椭。最近的操作得到的結(jié)果為負(fù)數(shù)
OF:溢出標(biāo)志忽匈。最近的操作導(dǎo)致一個補碼溢出——正溢出或負(fù)溢出
CMP a,b 相當(dāng)于b-a
TEST a,b 相當(dāng)于a&b。如果結(jié)果為0矿辽,則ZF位置1丹允。
跳轉(zhuǎn)指令:
直接跳轉(zhuǎn) jmp label
間接跳轉(zhuǎn)郭厌,通過讀取寄存器或內(nèi)存中的值,確定跳轉(zhuǎn)目標(biāo):
用寄存器%rax中的值作為跳轉(zhuǎn)目標(biāo):jmp *%rax
用%rax中的值指向的內(nèi)存中的值嫌松,作為跳轉(zhuǎn)目標(biāo): jmp *(%rax)
jmp是無條件跳轉(zhuǎn)沪曙,je jne 等是有條件跳轉(zhuǎn),即滿足條件才會跳轉(zhuǎn)萎羔。不同的指令對不同的條件碼進(jìn)行判斷液走,從而決定是否跳轉(zhuǎn)。如je指令判斷 ZF是否為1贾陷,為1就跳轉(zhuǎn)缘眶,否則不跳轉(zhuǎn)。
條件跳轉(zhuǎn)只能是直接跳轉(zhuǎn)髓废。
循環(huán):
使用 cmp 和條件跳轉(zhuǎn)即可實現(xiàn)do-while巷懈,while,for循環(huán)慌洪。在c語言中顶燕,可以使用goto語句來模擬jmp的過程。
witch語句:
switch語句比較特別冈爹,里面有很多個跳轉(zhuǎn)分支涌攻,通過一個跳轉(zhuǎn)表將可能的跳轉(zhuǎn)保存起來(看上去是一個數(shù)組),通過switch中的判斷條件進(jìn)行下標(biāo)定位频伤,在跳轉(zhuǎn)表中對應(yīng)一個跳轉(zhuǎn)標(biāo)識恳谎,即可直接跳轉(zhuǎn)到某個代碼段。break語句就是跳轉(zhuǎn)到switch之外的代碼片段憋肖,如果程序中沒有break語句因痛,那么匯編代碼也不會有jmp語句,所以會繼續(xù)執(zhí)行下一個代碼判斷岸更。與高級語言表現(xiàn)一致鸵膏。
過程:
在函數(shù)調(diào)用時(call指令),必須保存當(dāng)前函數(shù)的下一條指令地址坐慰,壓入棧中(%rsp寄存器指向棧頂)较性,然后將要跳轉(zhuǎn)的地址設(shè)置到rip寄存器中(程序計數(shù)器),調(diào)用結(jié)束時结胀,將棧頂?shù)牡刂窂棾鲈蘖湃雛ip中繼續(xù)執(zhí)行。
參數(shù)傳遞:
參數(shù)的傳遞可以通過%rdi,%rsi和其他寄存器傳遞糟港。但是通過寄存器只能傳遞6個攀操。如果多于6個參數(shù),則需要擴(kuò)充棧幀秸抚,將參數(shù)push到棧頂速和,然后調(diào)用之后通過%rsp的值加上偏移量訪問到參數(shù)的值歹垫。參數(shù)在棧中的大小總是8字節(jié),便于取參颠放。所以最后的結(jié)果是棧頂是返回地址(下一條指令的地址)排惨,棧頂下面的是第7個參數(shù),再下面是第8個參數(shù)等等碰凶。
過程的返回值是通過%rax寄存器傳遞的暮芭。
對于函數(shù)調(diào)用者,如果在調(diào)用函數(shù)時欲低,傳遞的參數(shù)里面有局部變量的地址辕宏,則需要將局部變量保存到棧中,以便被調(diào)用的函數(shù)能夠通過地址訪問到變量砾莱。當(dāng)函數(shù)調(diào)用者返回的時候瑞筐,需要銷毀局部變量,即將棧指針移動一些字節(jié)腊瑟。
寄存器中的局部存儲空間
寄存器是被所有過程共享的聚假,所以在進(jìn)行過程調(diào)用的時候,必須要保存好寄存器的值闰非,在過程結(jié)束的時候魔策,還原寄存器的值。
所以棧結(jié)構(gòu)中河胎,有一塊區(qū)域是“保存的寄存器”,
由被調(diào)用的過程保存的寄存器有%rbx,%rbp,%r12~%r15虎敦。所有其他寄存器游岳,除了棧指針$rsp,都分類為調(diào)用者保存寄存器其徙,其他任何函數(shù)都能修改它們胚迫。所以每個過程的局部變量超過6個的時候,要自己保存在棧中唾那,然后再調(diào)用過程访锻,否則局部變量可能會被其他過程修改。
所以一個函數(shù)首先應(yīng)該保存“由調(diào)用者保存的寄存器”中會用到的寄存器的值闹获,保存在棧中期犬,在函數(shù)結(jié)束的時候,要彈棧避诽,恢復(fù)這些寄存器的值龟虎。