條件碼寄存器
CF:進(jìn)位標(biāo)志寄存器,它記錄無(wú)符號(hào)操作的溢出,當(dāng)溢出時(shí)會(huì)被設(shè)為1
ZF:零標(biāo)志寄存器,當(dāng)計(jì)算結(jié)果為0時(shí)將會(huì)被設(shè)為1。
SF:符號(hào)標(biāo)志寄存器,當(dāng)計(jì)算結(jié)果為負(fù)數(shù)時(shí)會(huì)被設(shè)為1。
OF:溢出標(biāo)志寄存器,當(dāng)計(jì)算結(jié)果導(dǎo)致了補(bǔ)碼溢出時(shí),會(huì)被設(shè)為1。
cmp
cmp是compare的意思,它有兩個(gè)操作數(shù),比如cmp S2,S1,最終會(huì)基于S1-S2的值去設(shè)置條件碼寄存器的值
cmpl %edx,%eax這個(gè)指令來(lái)講,假設(shè)%edx的值為y,%eax的值為x。則當(dāng)x=y時(shí),ZF將會(huì)被置為1。當(dāng)x<y時(shí),SF將會(huì)被置為1。而當(dāng)x>y時(shí),ZF和SF將同時(shí)為0
條件碼寄存器的組合
- e->ZF(相等):e是equals的意思。這里代表的組合是ZF,因?yàn)閆F在結(jié)果為0時(shí)設(shè)為1,即a-b=0,也就是說(shuō)a==b。因此ZF代表的意義是相等。
- ne->~ZF(不相等):ne是not equals的意思。這里代表的組合是~ZF,也就是ZF做“非運(yùn)算”,則很明顯是不相等的意思。
- s->SF(負(fù)數(shù)):s這里沒(méi)什么實(shí)際意義,因?yàn)樨?fù)數(shù)的直譯是negative number,首字母是n,這與not的首字母重復(fù)了,因此這里就取了SF條件碼寄存器的首個(gè)字母(純屬LZ的猜測(cè),無(wú)權(quán)威證明,不過(guò)LZ自我感覺(jué)應(yīng)該八九不離十,0.0)。這里代表的組合是SF,因?yàn)镾F在計(jì)算結(jié)果為負(fù)數(shù)時(shí)設(shè)為1,此時(shí)可以認(rèn)為b為0,即a<0。因此這里是負(fù)數(shù)的意思。
- ns→~SF(非負(fù)數(shù)):與s相反,加上n則是not的意思,因此這里代表非負(fù)數(shù)。
- l->SFOF(有符號(hào)的小于):l代表的是less。這里的組合是SFOF,即對(duì)SF和OF做“異或運(yùn)算”?!爱惢蜻\(yùn)算”的意思則是代表,SF和OF不能相等。那么有兩種情況,當(dāng)OF為0時(shí),則代表沒(méi)有溢出,此時(shí)SF必須為1,SF為1則代表結(jié)果為負(fù)。即a-b<0,也就是a<b,也就是小于的意思。當(dāng)OF為1時(shí),則代表產(chǎn)生了溢出,而此時(shí)SF必須為0,也就是說(shuō)結(jié)果最后為正數(shù),那么此時(shí)則是負(fù)溢出,也可以得到a-b<0,即a<b。綜合前面兩種情況,SF^OF則代表小于的意思。
- le->(SF^OF)|ZF(有符號(hào)的小于等于):le是less equals的意思。有了前面小于的基礎(chǔ),這里就很容易理解了。SF^OF代表小于,ZF代表等于,因此兩者的“或運(yùn)算”則代表小于等于。
- g→(SF^OF)&ZF(有符號(hào)的大于):g是greater的意思。這里的組合是(SF^OF)&ZF,相對(duì)來(lái)說(shuō)就比較復(fù)雜了。不過(guò)有了前面的鋪墊,這個(gè)也非常好理解。SFOF代表小于,則~(SFOF)代表大于等于,而ZF代表不等于,將(SF^OF)與~ZF取“與運(yùn)算”,則代表大于等于且不等于,也就是大于。
- ge->~(SF^OF)(有符號(hào)的大于等于):ge是greater equals的意思。這個(gè)組合就不需要再解釋了吧。
- b->CF(無(wú)符號(hào)的小于):b是below的意思。CF是無(wú)符號(hào)溢出標(biāo)志,這里的意思是指如果a-b結(jié)果溢出了,則代表a是小于b的,即a<b。其實(shí)這個(gè)結(jié)論很顯然,關(guān)鍵點(diǎn)就在于,無(wú)符號(hào)減法只有在減出負(fù)數(shù)的時(shí)候才可能溢出,也就是說(shuō)只要結(jié)果溢出了,那么一定有a-b<0。因此這個(gè)結(jié)論就顯而易見(jiàn)了。
- be->CF|ZF(無(wú)符號(hào)的小于等于):這里是below equals的意思。因此這里會(huì)與ZF計(jì)算“或運(yùn)算”,字面上也很容易理解,即CF(小于)|(或)ZF(等于),也就是小于等于
- a→CF&ZF(無(wú)符號(hào)的大于):a代表的是above。這個(gè)組合也是非常好理解的,CF代表小于,則CF代表大于等于,ZF代表不等于,因此CF&ZF則代表大于等于且不等于,即大于。
- ae->~CF(無(wú)符號(hào)的大于等于):ae是above equals的意思
測(cè)試demo

ifelseswitch1.png

ifelseswitch2.png
打印出來(lái)的結(jié)果都是4,但是效率那個(gè)高呢?

ifelseswitch3.png
可以看到if-else 是一條條命令的判斷,最終匹配的最佳項(xiàng)才停止運(yùn)行

ifelseswitch4.png
接下來(lái)更改條件看看看看

ifelseswitch5.png

ifelseswitch6.png

ifelseswitch7.png

ifelseswitch8.png
0x100000ec8 <+72>: movslq (%rax,%rcx,4), %rdx (rdx來(lái)源于前面的計(jì)算,簡(jiǎn)而言之就是來(lái)源于變量值減去最小條件的差值),另外4個(gè)字節(jié)說(shuō)明內(nèi)存是連續(xù)的,至少在這里是這樣
0x100000ecc <+76>: addq %rax, %rdx
0x100000ecf <+79>: jmpq *%rdx
其實(shí)上面這幾句就是核心代碼,前面兩行算好內(nèi)存地址,第三步直接跳到相應(yīng)的執(zhí)行方法,不需要和if 一行行比較
這里有個(gè)問(wèn)題,那如果中間有一個(gè)值非常大的話,那么是不是會(huì)空出一段內(nèi)存空間,造成浪費(fèi)

ifelseswitch9.png
2-100 之間的連續(xù)內(nèi)存是不是就會(huì)浪費(fèi)掉?

ifelseswitch10.png
這種情況可以發(fā)現(xiàn)其實(shí)和if-else 一樣的了,所以寫(xiě)代碼的時(shí)候自己含量,switch其實(shí)就是用空間換時(shí)間來(lái)提高效率