目录
跳转的分类
cmp指令
尝试:使用CMP指令写一个简单的循环
条件跳转
现在我们终于向更加复杂的程序迈出更加坚实的一步,下面我们来系统的聊聊跳转这个事情!
跳转的分类
汇编语言中的条件执行是通过几个循环和分支指令来完成的。这些指令可以更改程序中的控制流。在两种情况下观察到条件执行
-  无条件跳转 - 这是通过JMP指令执行的。条件执行通常涉及将控制权转移到不遵循当前执行指令的指令的地址。控制权的转移可以是前进的(执行新的指令集),也可以是后退的(重新执行相同的步骤)。 
-  有条件跳转 - 这取决于条件由一组跳转指令j <condition>执行。条件指令通过中断顺序流程来转移控制,而它们通过更改IP中的偏移值来进行控制。
换而言之,一个是来了就跳转,看到jmp就三七二十一直接跑到label所在的地方继续执行。另一方面则是需要一定的条件——比如说必须小于7了才能跳转,等等!
cmp指令
cmp指令比较两个操作数。它通常用于条件执行中。该指令基本上从另一个操作数中减去一个操作数,以比较操作数是否相等。它不会干扰目标或源操作数。它与条件跳转指令一起用于决策。
cmp destination, source
cmp比较两个数字数据字段。目标操作数可以在寄存器中或在内存中。源操作数可以是常量(立即数)数据,寄存器或内存。
cmp DX, 00 ; 将DX值与0进行比较 je L7 ; 如果等于,则跳转到标签L7 ... L7: ...
cmp 通常用于比较计数器值是否已达到需要运行循环的次数。考虑以下典型条件-
INC EDX CMP EDX, 10 ; 比较计数器是否达到10 JLE LP1 ; 如果它小于或等于10,则跳转到LP1
换而言之,现在我们可以写循环了
尝试:使用CMP指令写一个简单的循环
程序需要循环9次打印一个字符串:
I am looping lol,当然,前面需要加上当前打印剩余的次数:charliechen@Charliechen:~/demo/demo10$ ./result 9: I am looping lol 8: I am looping lol 7: I am looping lol 6: I am looping lol 5: I am looping lol 4: I am looping lol 3: I am looping lol 2: I am looping lol 1: I am looping lol
提示:哈?这个简单,不需要提示 :),非得要提示的话,那就是好好看看上面的阐述
答案如下:
; help announce a typical string
%macro ANNOUNCE_STRING 2%1 db %2%1_LEN equ $ - %1
%endmacro
; fast use of common value
%define MY_STDOUT       1
%define MY_SYS_WRITE    4
%define MY_STDIN        0
%define MY_SYS_READ     3
; print string in a simple way
%macro PRINT_STRING 2mov edx, %2mov ecx, %1mov ebx, MY_STDOUTmov eax, MY_SYS_WRITEint 0x80
%endmacro
%macro EASY_PRINT_STRING 1PRINT_STRING %1, %1_LEN 
%endmacro
%macro EXIT 0mov ebx, 0mov eax, 1int 0x80
%endmacro
section .data PR_TIMES equ 9ANNOUNCE_STRING TELL_TIMES, {": "}ANNOUNCE_STRING BUFFER, {"I am looping lol", 0xA}
section .bsscurrent_times resb 1current_times_for_print resb 1
section .textglobal _start
_start:mov ax, PR_TIMESmov [current_times], ax
_do_loop:mov ax, [current_times]add ax, '0'mov [current_times_for_print], axPRINT_STRING current_times_for_print, 1EASY_PRINT_STRING TELL_TIMESEASY_PRINT_STRING BUFFERdec byte [current_times]cmp byte [current_times], 0jne _do_loop                ; jmp out! if the counter goes 0EXIT 
Bonus: 你可以试试看让用户控制循环次数?
条件跳转
如果在条件跳转中满足某些指定条件,则控制流将转移到目标指令。根据条件和数据,有许多条件跳转指令。以下是用于算术运算的有符号数据的条件跳转指令-
| 指令 | 描述 | 标志测试 | 
|---|---|---|
| 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 | 
笔者目前建议是:如果不是在优化阶段或者是确实需要,可以不理睬上面的绝大多指令!