汇编语言入门:流程控制
流程控制:顺序,分支,循环
程序计数器PC中存储当前执行的程序在EM中的位置
汇编里面,用比较、跳转实现流程控制.
1.顺序:PC+1(不一定加一,看指令长度)
2.分支循环,直接赋给PC值,执行指定地址的程序
有时候需要程序有一定的流程控制能力,它不是老老实实按照顺序来执行的,中间可能会跳过一些代码
修改PC值,不可用MOV指令,PC是特殊的寄存器,特殊对待,跳转指令修改其值。
跳转指令:
1 ja 大于时跳转 2 jae 大于等于 3 jb 小于 4 jbe 小于等于 5 je 相等 6 jna 不大于 7 jnae 不大于或者等于 8 jnb 不小于 9 jnbe 不小于或等于 10 jne 不等于 11 jg 大于(有符号) 12 jge 大于等于(有符号) 13 jl 小于(有符号) 14 jle 小于等于(有符号) 15 jng 不大于(有符号) 16 jnge 不大于等于(有符号) 17 jnl 不小于 18 jnle 不小于等于 19 jns 无符号 20 jnz 非零 21 js 如果带符号 22 jz 如果为零
1 a: above 2 e: equal 3 b: below 4 n: not 5 g: greater 6 l: lower 7 s: signed 8 z: zero
C语言的if语句:
int main() { int a = 50; if( a > 10 ) { a = a - 10; } return a; }
其汇编程序:
global main main: mov eax, 50 cmp eax, 10 ; 对eax和10进行比较 jle xiaoyu_dengyu_shi ; 小于或等于的时候跳转 sub eax, 10 xiaoyu_dengyu_shi: ret
- 第一条,cmp指令,专门用来对两个数进行比较
- 第二条,条件跳转指令,当前面的比较结果为“小于或等于”的时候就跳转,否则不跳转
即:比较eax和10,eax小于等于10的时候,跳过中间的减法
- C语言中:a大于10的时候,进入if块中执行减法
- 汇编语言中:eax小于等于10的时候,跳过中间的减法
同样,比较a<10 a<=10 a==10 a>=10同理
C语言的while循环:
int sum = 0; int i = 1; while( i <= 10 ) { sum = sum + i; i = i + 1; }
C语言中不使用循环怎么实现循环的功能:用跳转!
int sum = 10; int i = 1; _start: if( i <= 10 ) { sum = sum + i; i = i + 1; goto _start; }
变形:
1 if( a <= 10 ) goto out_of_block; 2 3 // some code 4 5 out_of_block:
if块里只需要放一条跳转语句即可
if里的条件是反过来的
跳转语句的功能是跳过“正宗C代码”的if块
int sum = 10; int i = 1; _start: if( i > 10 ) { goto _end_of_block; } sum = sum + i; i = i + 1; goto _start; _end_of_block:
为什么要变形?我们需要if块中都仅有一条goto语句!
逐行翻译为汇编:
global main main: mov eax, 0 mov ebx, 1 _start: cmp ebx, 10 jg _end_of_block add eax, ebx add ebx, 1 jmp _start _end_of_block: ret
单条goto语句可以直接用jmp语句替代
if和goto组合的语句块可以用cmp和j*指令的组合替代
综上:
汇编实现while
- 将while循环拆解成只有if和goto的形式
- 将if形式的语句拆解成if块中仅有一行goto语句的形式
- 从前往后逐行翻译成汇编语言
do-while循环、for循环可转为while循环
感谢:https://zhuanlan.zhihu.com/p/23902265