程序流程控制

指令指针

无条件跳转

  • 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
      • 格式
	< 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:

优化分支命令

  • 分支预测
    • 条件分支
      • 向后的分支假设会被执行
      • 向前的分支假设不会被执行
      • 上次被执行的分支会被再次执行
    • 无条件跳转
  • 优化秘诀
    • 消除分支
    • 代码可以预测的分支优先
    • 展开分支
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章