程序流程控制

指令指針

無條件跳轉

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

優化分支命令

  • 分支預測
    • 條件分支
      • 向後的分支假設會被執行
      • 向前的分支假設不會被執行
      • 上次被執行的分支會被再次執行
    • 無條件跳轉
  • 優化祕訣
    • 消除分支
    • 代碼可以預測的分支優先
    • 展開分支
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章