目录
现在我们终于向更加复杂的程序迈出更加坚实的一步,下面我们来系统的聊聊跳转这个事情!
跳转的分类
汇编语言中的条件执行是通过几个循环和分支指令来完成的。这些指令可以更改程序中的控制流。在两种情况下观察到条件执行
-
无条件跳转 - 这是通过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 2 mov edx, %2 mov ecx, %1 mov ebx, MY_STDOUT mov eax, MY_SYS_WRITE int 0x80 %endmacro %macro EASY_PRINT_STRING 1 PRINT_STRING %1, %1_LEN %endmacro %macro EXIT 0 mov ebx, 0 mov eax, 1 int 0x80 %endmacro section .data PR_TIMES equ 9 ANNOUNCE_STRING TELL_TIMES, {": "} ANNOUNCE_STRING BUFFER, {"I am looping lol", 0xA} section .bss current_times resb 1 current_times_for_print resb 1 section .text global _start _start: mov ax, PR_TIMES mov [current_times], ax _do_loop: mov ax, [current_times] add ax, '0' mov [current_times_for_print], ax PRINT_STRING current_times_for_print, 1 EASY_PRINT_STRING TELL_TIMES EASY_PRINT_STRING BUFFER dec byte [current_times] cmp byte [current_times], 0 jne _do_loop ; jmp out! if the counter goes 0 EXIT
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 |
笔者目前建议是:如果不是在优化阶段或者是确实需要,可以不理睬上面的绝大多指令!
本站资源均来自互联网,仅供研究学习,禁止违法使用和商用,产生法律纠纷本站概不负责!如果侵犯了您的权益请与我们联系!
转载请注明出处: 免费源码网-免费的源码资源网站 » 基于x86_64汇编语言简单教程7:跳转
发表评论 取消回复