
彙編 - 條件
組合語言中的條件執行是通過幾個迴圈和分支指令實現的。這些指令可以改變程式的控制流程。條件執行在兩種情況下出現:
序號 | 條件指令 |
---|---|
1 | 無條件跳轉 這是由JMP指令執行的。條件執行通常涉及將控制轉移到當前正在執行的指令之後地址的指令。控制轉移可以是向前的,以執行一組新的指令,也可以是向後的,以重新執行相同的步驟。 |
2 | 條件跳轉 這是由一組跳轉指令j<condition>根據條件執行的。條件指令透過打破順序流程來轉移控制,它們透過更改IP中的偏移值來做到這一點。 |
在討論條件指令之前,讓我們先討論CMP指令。
CMP指令
CMP指令比較兩個運算元。它通常用於條件執行。此指令基本上從另一個運算元中減去一個運算元,以比較運算元是否相等。它不會干擾目標運算元或源運算元。它與條件跳轉指令一起用於決策。
語法
CMP destination, source
CMP比較兩個數值資料欄位。目標運算元可以位於暫存器或記憶體中。源運算元可以是常量(立即數)資料、暫存器或記憶體。
示例
CMP DX, 00 ; Compare the DX value with zero JE L7 ; If yes, then jump to label L7 . . L7: ...
CMP經常用於比較計數器值是否已達到迴圈需要執行的次數。考慮以下典型條件:
INC EDX CMP EDX, 10 ; Compares whether the counter has reached 10 JLE LP1 ; If it is less than or equal to 10, then jump to LP1
無條件跳轉
如前所述,這是由JMP指令執行的。條件執行通常涉及將控制轉移到當前正在執行的指令之後地址的指令。控制轉移可以是向前的,以執行一組新的指令,也可以是向後的,以重新執行相同的步驟。
語法
JMP指令提供一個標籤名稱,控制流立即轉移到該標籤。
JMP label
示例
以下程式碼片段說明了JMP指令:
MOV AX, 00 ; Initializing AX to 0 MOV BX, 00 ; Initializing BX to 0 MOV CX, 01 ; Initializing CX to 1 L20: ADD AX, 01 ; Increment AX ADD BX, AX ; Add AX to BX SHL CX, 1 ; shift left CX, this in turn doubles the CX value JMP L20 ; repeats the statements
條件跳轉
如果條件跳轉中滿足某些指定的條件,則控制流將轉移到目標指令。根據條件和資料,有許多條件跳轉指令。
以下是用於算術運算的有符號資料的條件跳轉指令:
指令 | 描述 | 測試的標誌 |
---|---|---|
JE/JZ | 相等跳轉或零跳轉 | ZF |
JNE/JNZ | 不相等跳轉或非零跳轉 | ZF |
JG/JNLE | 大於跳轉或不小於/等於跳轉 | OF, SF, ZF |
JGE/JNL | 大於/等於跳轉或不小於跳轉 | OF, SF |
JL/JNGE | 小於跳轉或不大於/等於跳轉 | OF, SF |
JLE/JNG | 小於/等於跳轉或不大於跳轉 | OF, SF, ZF |
以下是用於邏輯運算的無符號資料的條件跳轉指令:
指令 | 描述 | 測試的標誌 |
---|---|---|
JE/JZ | 相等跳轉或零跳轉 | ZF |
JNE/JNZ | 不相等跳轉或非零跳轉 | ZF |
JA/JNBE | 高於跳轉或不低於/等於跳轉 | CF, ZF |
JAE/JNB | 高於/等於跳轉或不低於跳轉 | CF |
JB/JNAE | 低於跳轉或不高於/等於跳轉 | CF |
JBE/JNA | 低於/等於跳轉或不高於跳轉 | AF, CF |
以下條件跳轉指令具有特殊用途並檢查標誌的值:
指令 | 描述 | 測試的標誌 |
---|---|---|
JXCZ | 如果CX為零則跳轉 | 無 |
JC | 進位跳轉 | CF |
JNC | 無進位跳轉 | CF |
JO | 溢位跳轉 | OF |
JNO | 無溢位跳轉 | OF |
JP/JPE | 奇偶校驗跳轉或偶校驗跳轉 | PF |
JNP/JPO | 無奇偶校驗跳轉或奇校驗跳轉 | PF |
JS | 符號跳轉(負值) | SF |
JNS | 無符號跳轉(正值) | SF |
J<condition>指令集的語法:
示例:
CMP AL, BL JE EQUAL CMP AL, BH JE EQUAL CMP AL, CL JE EQUAL NON_EQUAL: ... EQUAL: ...
示例
以下程式顯示三個變數中最大的一個。這些變數是兩位數變數。三個變數num1、num2和num3的值分別為47、22和31:
section .text global _start ;must be declared for using gcc _start: ;tell linker entry point mov ecx, [num1] cmp ecx, [num2] jg check_third_num mov ecx, [num2] check_third_num: cmp ecx, [num3] jg _exit mov ecx, [num3] _exit: mov [largest], ecx mov ecx,msg mov edx, len mov ebx,1 ;file descriptor (stdout) mov eax,4 ;system call number (sys_write) int 0x80 ;call kernel mov ecx,largest mov edx, 2 mov ebx,1 ;file descriptor (stdout) mov eax,4 ;system call number (sys_write) int 0x80 ;call kernel mov eax, 1 int 80h section .data msg db "The largest digit is: ", 0xA,0xD len equ $- msg num1 dd '47' num2 dd '22' num3 dd '31' segment .bss largest resb 2
編譯並執行上述程式碼後,將產生以下結果:
The largest digit is: 47