我們知道cmp是比較兩個暫存器內容的指令,但這是如何實現的?
當執行到cmp指令的時候會讀取這兩個暫存器的內容,並加以減法運算,結果本身不保留,並按照結果設定符號位(屬算術運算)。
cmp是乙個經常使用的指令,大多用來測試數字的大小。乙個常見的例子當執行到test指令的時候會讀取這兩個暫存器的內容,並加以按位與運算,結果不保留,並按照結果設定符號位(屬邏輯運算)。mov eax, 10mov eax, 10
cmp eax, ebx ;相減求出結果,為0,將1存入zf
je some_where ;檢查zf,為1就跳
jne some_where ;檢查zf,為0就跳
test是乙個用來檢測內容而不是運算內容的,經常用的一招是測試暫存器是否為0:這些符號位存在乙個叫做psw(program status word,程式狀態字)的16位(4位元組)暫存器裡面。test eax, eax某個參考資料說jz some_where
test eax,ebx
與and eax,ebx
是一樣的,竊以為不同,因為彙編的所有算術指令都是破壞性的,它會把結果存入 eax,而test不會(就像c**a &= b;
)。若要 and 也不會破壞原值,只能先入棧存值,然後在出棧前轉移結果,就像如下所示:mov eax, ?? ;賦值但是你要自己做乙個cmp指令是不切實際的,因為你自己還是要判斷符號位的值,最終還是用到了test, cmp這些指令。mov ebx, ??
push eax ;入棧儲存eax
and eax, ebx ;運算
mov edx, eax ;儲存結果
pop eax ;彈出恢復eax
符號位敘述
典型應用
of溢位標誌,標明乙個溢位的運算。真置1,假置0。
這個溢位,非溢位,我想我還沒有弄懂
sf負號標誌,標明結果為負數。真置1,假置0。
int i = -100;
if(i < 0)
goto somewhere;
zf零標誌,標明結果為0。真置1,假置0。
見上cmp例子
cf進製標誌,標明結果進製了。真置1,假置0。
mov eax,1
mov ebx,9
add eax,ebx
af輔助進製標誌,記錄運算時第3位(半個位元組)產生的進製。
pf奇偶標誌,結果運算元中1的個數為偶置1(我猜是二進位制下)。
df方向標誌,在串處理指令中控制資訊的方向(非運算)
(null)
if中斷標誌(非運算)
(null)
tf陷井標誌(非運算)
(null)
其中前幾個稱為運算條件碼(condition code),後三個是邏輯控制標誌位,我們在此對它們不感興趣。
jcc指條件跳轉指令,cc就是指條件碼。
jcc指令
中文含義
英文原意
檢查符號位
典型c應用
jz/je
若為0則跳轉;
若相等則跳轉
jump if zero;
jump if equal
zf=1
if (i == j);
if (i == 0);
jnz/jne
若不為0則跳轉;
若不相等則跳轉
jump if not zero;
jump if not equal
zf=0
if (i != j);
if (i != 0);
js若為負則跳轉
jump if sign
sf=1
if (i < 0);
jns若為正則跳轉
jump if not sign
sf=0
if (i > 0);
jp/jpe
若1出現次數為偶數則跳轉
jump if parity (even)
pf=1
(null)
jnp/jpo
若1出現次數為奇數則跳轉
jump if not parity (odd)
pf=0
(null)
jo若溢位則跳轉
jump if overflow
of=1
(null)
jno若無溢位則跳轉
jump if not overflow
of=0
(null)
jc/jb/jnae
若進製則跳轉;
若低於則跳轉;
若不高於等於則跳轉
jump if carry;
jump if below;
jump if not above equal
cf=1
if (i < j);
jnc/jnb/jae
若無進製則跳轉;
若不低於則跳轉;
若高於等於則跳轉;
jump if not carry;
jump if not below;
jump if above equal
cf=0
if (i >= j);
jbe/jna
若低於等於則跳轉;
若不高於則跳轉
jump if below equal;
jump if not above
zf=1或cf=1
if (i <= j);
jnbe/ja
若不低於等於則跳轉;
若高於則跳轉
jump if not below equal
jump if abow
zf=0或cf=0
if (i > j);
jl/jnge
若小於則跳轉;
若不大於等於則跳轉
jump if less
jump if not greater equal
sf != of
if (si < sj);
jnl/jge
若不小於則跳轉;
若大於等於則跳轉;
jump if not less;
jump if greater equal
sf = of
if (si >= sj);
jle/jng
若小於等於則跳轉;
若不大於則跳轉
jump if less equal;
jump if not greater
zf != of 或 zf=1
if (si <= sj);
jnle/jg
若不小於等於則跳轉;
若大於則跳轉
jump if not less equal
jump if greater
sf=0f 且 zf=0
if(si>sj)
這裡有好多相等的指令(啊哈,這裡有乙個有意思的現象,好多看似不沾邊的東西實際上是相等的!),我猜是因為編譯器編譯起來就更方便了,不過做乙個表也沒什麼難的,這個結論不成立啊……
這裡有一點要指出,無符號數用低於、高於來比較,而有符號數用大於、小於比較。
Linux C語言內聯彙編 條件跳轉
void jump 當sum的約束條件是 r 時,內聯彙編中應該初始化一下,movl 0,0 相當於初始化sum的中轉暫存器 比如下面,編譯器選擇 edx來暫存sum,如果不清零操作,其中的值是不確定的 再看看生成的.s檔案 subq 16,rsp movl 10,4 rbp movl 0,8 rb...
x86彙編 條件跳轉
條件跳轉表 直接轉移指令 指令格式 機器碼 測試標誌 條件說明 符號 jo opr 70of 1 結果有溢位 jno opr 71of 0 結果無溢位 jc opr 72cf 1 小於 jnc opr 73cf 0 大於或等於 jz je opr 74zf 1 結果為0 jnz jne opr 75...
shell if命令 判斷條件整理
語法結構 一行 if 1x ip x then echo abc fi 多行 if 1x ab x then echo you had enter ab elif 1x cd x then echo you had enter cd else echo you had enter unexpecte...