指令指针
无条件跳转
- Jumps
- 格式
jmp location - 分类
- short jump (offset less than 128 bytes)
- Near jump
- Far jump (jump to another segment)
- 示例
- 格式
#jumptest.s - An example of the jmp instruction
.section .text
.globl _start
_start:
nop
mov $1, %eax
jmp overwhere
mov $10, %ebx
int 0x80
overwhere:
mov $20, %ebx
int $0x80
运行后使用 echo $? 查看返回值
- Calls
- 格式
call address - 函数模板
- 格式
function_label:
pushl %ebp
movl %esp, %ebp
< normal function code goes here >
movl %ebp, %esp
popl %ebp
ret
* 示例
# calltest.s - An example of using the CALL instruction
.section .data
output:
.asciz "This is section %d\n"
.section .text
.globl _start
_start:
push $1
push $output
call printf
add $8, %esp
call overwhere
pushl $3
pushl $output
call printf
add $8, %esp
pushl $0
call exit
overwhere:
pushl %ebp
mov %esp, %ebp
pushl $2
pushl $output
call printf
add $8, %esp
movl %ebp, %esp
popl %ebp
ret
- Interrupts
- 软中断
- 硬中断
条件跳转
- 格式
jxx address
指令 | 描述 | 标志位 |
---|---|---|
JA | 如果大于跳转 | CF=0 and ZF=0 |
JAE | 大于或等于跳转 | CF=0 |
JB | 小于跳转 | CF=1 |
JBE | 小于或者等于跳转 | CF=1 or ZF=1 |
JC | 如果进位跳转 | CF=1 |
JCXZ | 如果cx=0跳转 | |
JECXZ | 如果exc=0跳转 | |
JE | 等于跳转 | ZF=1 |
JG | 大于跳转 | ZF=0andSF=OF |
JGE | 大于或等于 | SF=OF |
JL | 小于跳转 | SF!=OF |
JLE | 小于或等于跳转 | ZF=1 或SF!=OF |
JNA | 如果不大于跳转 | CF=1 或者 ZF=1 |
JNAE | 不大于等于跳转 | CF=1 |
JNB | 不小于跳转 | CF=0 |
JNBE | 不小于等于跳转 | CF=0且ZF=0 |
JNC | 没有进位跳转 | CF=0 |
JNE | 不等于跳转 | ZF=0 |
JNG | 不大于跳转 | ZF=1或SF!=OF |
JNGE | 不大于等于跳转 | SF!=OF |
JNL | 不小于跳转 | SF=OF |
JNLE | 不小于等于跳转 | ZF=0且SF=OF |
JNO | 没有溢出跳转 | OF=0 |
JNP | 奇偶位不为1跳转 | PF=0 |
JNS | 符号位没有设置跳转 | SF=0 |
JNZ | 不为0跳转 | ZF=0 |
JO | 溢出跳转 | |
JP | 奇偶位设置跳转 | PF=1 |
JPE | 如果奇偶位位偶数跳转 | PF=1 |
JPO | 奇偶位位奇数跳转 | PF=0 |
JS | 如果为正跳转 | SF=1 |
JZ | 如果为零跳转 | ZF=1 |
- 比较指令
- 格式
cmp aperand1, operand2(operand2-operand1)
- 格式
- 使用标志位
- 使用零标志位
movl $10, %edi
loop1:
< other code instructions>
dec %edi
jz out
jmp loop1
out:
* 使用溢出标志
movl $1, %eax
movb $0x7f, %bl
addb $10, %bl
jo overhere
int $0x80
overhere:
movl $0, %ebx
int $0x80
* 使用奇偶进位标识
# paritytest.s - An example of testing the parity flag
.section .text
.globl _start
_start:
movl $1, %eax
movl $4, %ebx
subl $3, %ebx
jp overhere
int 0x80
overhere:
movl $100, %ebx
int $0x80
* 使用标志位
# signtest.s - An example of using the sign flag
.section .data
value:
.int 21, 15, 34, 11, 6, 50, 32, 80, 10, 2
output:
.asciz "The value is: %d\n"
.section .text
.globl _start
_start:
movl $9, %edi
loop:
pushl vlaue(, %edi, 4)
pushl $output
call printf
add $8, %esp
dec %edi
jns loop
movl $1, %eax
movl $0, %ebx
int $0x80
* 使用进位标识
* CLC 将进位标志设置位0
* CMC 将进位标志取反
* STC 设置进位标志位1
循环
- 循环指令
- LOOP 循环直到ecx等于0
- 格式
loop address - 格式
- 格式
- LOOP 循环直到ecx等于0
< code before the loop >
movl $100, %ecx
loop1:
< code to loop throuth >
loop loop1
< code after the loop >
* 示例
# loop.s - An example of the loop instruction
.section .data
output:
.asciz "The value is: %d\n"
.section .text
.globl _start
_start:
movl $100, %ecx
movl $0, %eax
loop1:
add1 %ecx, %eax
loop loop1
pushl %eax
pushl $output
call printf
add $8, %esp
movl $1, %eax
movl $0, %ebx
int $0x80
* LOOPE/LOOPZ 直到ecx=0/zf=0
* LOOPNE/LOOPNZ 直到ecx!=0/zf=1
实现高级语言的分支语句
- if格式
if:
< condition to evaluate >
jxx else
< code to implement the "then" statements >
jmp end
else:
< code to implement the "else" statements >
end:
- for格式
for:
< condition to evaluate for loop counter value>
jxx forcode
jmp end
forcode:
< for loop code to excute>
<increment for loop counter>
jmp for
end:
优化分支命令
- 分支预测
- 条件分支
- 向后的分支假设会被执行
- 向前的分支假设不会被执行
- 上次被执行的分支会被再次执行
- 无条件跳转
- 条件分支
- 优化秘诀
- 消除分支
- 代码可以预测的分支优先
- 展开分支