制作網(wǎng)站的知識免費推廣方式有哪些
本節(jié)解決了x86-64如何實現(xiàn)條件語句、循環(huán)語句和分支語句的問題
條件碼
除了整數(shù)寄存器外,cpu還維護著一組單個位的條件碼寄存器,用來描述最近的算數(shù)和邏輯運算的某些屬性。可檢測這些寄存器來執(zhí)行條件分支指令。
CF(Carry Flag):進位標志。最近的算術或邏輯運算使得最高位產生了進位??蓹z查無符號數(shù)操作的溢出。
ZF(Zero Flag):零標志。最近的算術或邏輯運算結果為0。
SF(Sign Flag):符號標志。最近的算術或邏輯運算結果為負數(shù)。
OF(Overflow Flag):溢出標志。最近的算術或邏輯運算導致補碼溢出——正溢出或負溢出。
這里指出,leaq不會改變任何條件碼,因為是被用來進行地址計算的。對于邏輯操作,例如XOR,進位和溢出標志會設置為0。對于移位操作,進位標志將設置為最后一個被移出的位,溢出標志設為0。INC和DEC指令會設置溢出和零標志,但不會改變進位標志。
除了基本的算術和邏輯指令會設置條件碼之外,還有兩類指令(8,16,32,64位形式)會設置條件碼。
CMP指令行為與SUB指令一致,只是不會改變目的寄存器。
TEST指令與AND指令一致,只是不會改變目的寄存器的值。
訪問條件碼
通常不會直接讀取條件碼。常用方法有三種:(1)根據(jù)條件碼的某種組合,將一個字節(jié)設置為0或者1。(2)可以條件跳轉到程序的某個其他的部分。(3)可以有條件的傳輸數(shù)據(jù)。
對于第一種情況,我們用SET這類指令設置某個字節(jié)為1或0。SET根據(jù)某些條件碼的算術或邏輯組合,將寄存器的某個低位字節(jié)或某個一個字節(jié)的內存位置置為1或0。
下圖是SET指令
需要注意SET指令在大小比較時有符號數(shù)和無符號數(shù)是不同的指令。
舉個例子分析下
我們來分析setl(有符號小于)具體是在那幾個條件碼的何種組合下進行工作的
cmpq獲得a - b,這里在運算時可能會有如下幾種情況
(1)未溢出,這時OF(溢出標志位)為0,則a - b的結果小于0那么a < b,根據(jù)a - b的結果小于0,SF被設為1。
(2)溢出,OF = 1,cmpq的結果由兩種情況:小于零,說明a - b > 0,只有這樣才會使得a和b進行補碼減法后負溢出;大于零,說明a - b < 0,只有這樣才會使得a和b進行補碼減法后正溢出。(等于零不會溢出)這就可以看出只有cmpq運算結果是正數(shù)才能說明a < b。于是SF = 0。
可以看出 OF和SF異或的結果是setl判斷的標準,若異或結果為1,說明a < b,%al被設為1;否則為0。
SET指令會區(qū)分有符號值和無符號值,這在匯編語言中并不常見,大多數(shù)情況,有符號數(shù)和無符號數(shù)都使用一樣的指令,因為許多算術運算對無符號數(shù)和補碼都有一樣的位級行為。部分情況需要使用不同的指令,例如,右移、除法、乘法。