C&汇编基础-循环语句
do…while 循环
源码
1
2
3
4
5
6
7
8
9void Function()
{
int i=0;
do
{
printf("%d\n",i);
i++;
}while(i<=100);
}反汇编
1 | 00401020 push ebp |
do…while语句的表现形式
JCC 指令会跳到循环语句的起始地址
JCC 指令所在的地址,就是循环语句块的结束地址
JCC 条件判断与源码相同
while 循环
- 源码
1 | void Function1() |
- 反汇编
1 | 00401070 push ebp |
while语句的表现形式
JCC 会跳出循环,条件判读跳转的地址的上面一个是 jmp 指令
程序块运行结束后会使用 jmp 指令跳转到循环的起始地址。程序块的结尾是 jmp 指令的地址
JCC 条件判断与源码相反
for 循环
- 源码
1 | void Function2() |
- 反汇编
1 | 0040B7F0 push ebp |
for 语句执行流程
执行参数1
执行参数2
执行循环语句
执行参数3
for 语句表现形式
第一个 jmp 指令前为赋初始值部分
第一个 jmp 指令所跳转的地址是循环条件的判断部分的起始地址
JCC 判断条件成立时跳转到循环体外
JCC 条件跳转地址上面有一个 jmp,jmp 地址为表达式3的起始位置
JCC 条件判断与源码相反
练习
正向代码
- 将两个变量的值交换
1 | void change(int x,int y) |
- 将一个数组中的数倒序输出
1 | void back() |
- 找出数组里最大的值,并返回
1 | int big() |
- 将数组中所有的值相加并返回
1 | int sum() |
- 打印一个数组中的所有的值
1 | void print() |
- 将两个等长数组相同位置的值相加,存储到另外一个等长数组中
1 | int plus() |
- 如果参数 x 是素数返回1,否则返回 0
1 | int prime(int x) |
- 俩俩比较数组的值,将最大的一个存储到数组的最后一个位置
1 | void paixu() |
- 判断数组是否是对称的,如果是返回 1,不是返回 0
1 | int duic() |
- 冒泡排序
冒泡排序原理:
- 比较相邻的元素。如果第一个比第二个大,就交换他们两个。
- 对每一对相邻元素做同样的工作,从开始第一对到结尾的最后一对。在这一点,最后的元素应该会是最大的数。
- 针对所有的元素重复以上的步骤,除了最后一个。
- 持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。
1 | void Bubble() |
数组+for循环(例1)
反汇编
1 | 00401190 push ebp |
还原步骤
- 截取程序代码
1 | 004011AB mov dword ptr [ebp-14h],1 |
- 分析参数
无
- 变量分析
[ebp-40h]:i
- 数组分析
数组是从栈的低地址到高地址存储的
空数组在反汇编中不会回显示
数组常见表现形式:[ebp+eax*数据类型宽度-最低地址]
先确认这里有几个不同的低地址
[ebp-14h];[ebp-28h]再确认数组的表现形式有几个
[ebp+ecx4-14h];[ebp+eax4-28h];[ebp+ecx*4-3Ch]然后确定有三个数组
[ebp-14h]:arr1
[ebp-28h]:arr2
[ebp-3Ch]:arr3
- 最后确认数组的类型和元素
dword:4 字节,int 型
int arr1[5] = {1,2,3,4,5}
int arr2[5] = {4,3,2,8,3,0}
int arr3[5]
- 分析循环
- 判断循环的执行流程
jmp起始(跳到条件判断)–>条件判断(跳出循环)–>jmp结束(跳到jmp起始后面)
很明显这是一个 for 循环
- 表达式1:第一个 jmp 前是变量赋值
i=0
- 表达式2:条件判断与源码相反
jg(大于):<=
比较值:i<=9
- 程序功能
arr3[i]=arr1[i]+arr2[i]
- 表达式3
i+1
- 返回值
无
- 代码还原
1 | void plus1() |
- 本文标题:C&汇编基础-循环语句
- 本文作者:9unk
- 创建时间:2021-04-01 14:18:28
- 本文链接:https://9unkk.github.io/2021/04/01/c-hui-bian-ji-chu-xun-huan-yu-ju/
- 版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!