爆款云主机2核4G限时秒杀,88元/年起!
查看详情

活动

天翼云最新优惠活动,涵盖免费试用,产品折扣等,助您降本增效!
热门活动
  • 618智算钜惠季 爆款云主机2核4G限时秒杀,88元/年起!
  • 免费体验DeepSeek,上天翼云息壤 NEW 新老用户均可免费体验2500万Tokens,限时两周
  • 云上钜惠 HOT 爆款云主机全场特惠,更有万元锦鲤券等你来领!
  • 算力套餐 HOT 让算力触手可及
  • 天翼云脑AOne NEW 连接、保护、办公,All-in-One!
  • 中小企业应用上云专场 产品组合下单即享折上9折起,助力企业快速上云
  • 息壤高校钜惠活动 NEW 天翼云息壤杯高校AI大赛,数款产品享受线上订购超值特惠
  • 天翼云电脑专场 HOT 移动办公新选择,爆款4核8G畅享1年3.5折起,快来抢购!
  • 天翼云奖励推广计划 加入成为云推官,推荐新用户注册下单得现金奖励
免费活动
  • 免费试用中心 HOT 多款云产品免费试用,快来开启云上之旅
  • 天翼云用户体验官 NEW 您的洞察,重塑科技边界

智算服务

打造统一的产品能力,实现算网调度、训练推理、技术架构、资源管理一体化智算服务
智算云(DeepSeek专区)
科研助手
  • 算力商城
  • 应用商城
  • 开发机
  • 并行计算
算力互联调度平台
  • 应用市场
  • 算力市场
  • 算力调度推荐
一站式智算服务平台
  • 模型广场
  • 体验中心
  • 服务接入
智算一体机
  • 智算一体机
大模型
  • DeepSeek-R1-昇腾版(671B)
  • DeepSeek-R1-英伟达版(671B)
  • DeepSeek-V3-昇腾版(671B)
  • DeepSeek-R1-Distill-Llama-70B
  • DeepSeek-R1-Distill-Qwen-32B
  • Qwen2-72B-Instruct
  • StableDiffusion-V2.1
  • TeleChat-12B

应用商城

天翼云精选行业优秀合作伙伴及千余款商品,提供一站式云上应用服务
进入甄选商城进入云市场创新解决方案
办公协同
  • WPS云文档
  • 安全邮箱
  • EMM手机管家
  • 智能商业平台
财务管理
  • 工资条
  • 税务风控云
企业应用
  • 翼信息化运维服务
  • 翼视频云归档解决方案
工业能源
  • 智慧工厂_生产流程管理解决方案
  • 智慧工地
建站工具
  • SSL证书
  • 新域名服务
网络工具
  • 翼云加速
灾备迁移
  • 云管家2.0
  • 翼备份
资源管理
  • 全栈混合云敏捷版(软件)
  • 全栈混合云敏捷版(一体机)
行业应用
  • 翼电子教室
  • 翼智慧显示一体化解决方案

合作伙伴

天翼云携手合作伙伴,共创云上生态,合作共赢
天翼云生态合作中心
  • 天翼云生态合作中心
天翼云渠道合作伙伴
  • 天翼云代理渠道合作伙伴
天翼云服务合作伙伴
  • 天翼云集成商交付能力认证
天翼云应用合作伙伴
  • 天翼云云市场合作伙伴
  • 天翼云甄选商城合作伙伴
天翼云技术合作伙伴
  • 天翼云OpenAPI中心
  • 天翼云EasyCoding平台
天翼云培训认证
  • 天翼云学堂
  • 天翼云市场商学院
天翼云合作计划
  • 云汇计划
天翼云东升计划
  • 适配中心
  • 东升计划
  • 适配互认证

开发者

开发者相关功能入口汇聚
技术社区
  • 专栏文章
  • 互动问答
  • 技术视频
资源与工具
  • OpenAPI中心
开放能力
  • EasyCoding敏捷开发平台
培训与认证
  • 天翼云学堂
  • 天翼云认证
魔乐社区
  • 魔乐社区

支持与服务

为您提供全方位支持与服务,全流程技术保障,助您轻松上云,安全无忧
文档与工具
  • 文档中心
  • 新手上云
  • 自助服务
  • OpenAPI中心
定价
  • 价格计算器
  • 定价策略
基础服务
  • 售前咨询
  • 在线支持
  • 在线支持
  • 工单服务
  • 建议与反馈
  • 用户体验官
  • 服务保障
  • 客户公告
  • 会员中心
增值服务
  • 红心服务
  • 首保服务
  • 客户支持计划
  • 专家技术服务
  • 备案管家

了解天翼云

天翼云秉承央企使命,致力于成为数字经济主力军,投身科技强国伟大事业,为用户提供安全、普惠云服务
品牌介绍
  • 关于天翼云
  • 智算云
  • 天翼云4.0
  • 新闻资讯
  • 天翼云APP
基础设施
  • 全球基础设施
  • 信任中心
最佳实践
  • 精选案例
  • 超级探访
  • 云杂志
  • 分析师和白皮书
  • 天翼云·创新直播间
市场活动
  • 2025智能云生态大会
  • 2024智算云生态大会
  • 2023云生态大会
  • 2022云生态大会
  • 天翼云中国行
天翼云
  • 活动
  • 智算服务
  • 产品
  • 解决方案
  • 应用商城
  • 合作伙伴
  • 开发者
  • 支持与服务
  • 了解天翼云
      • 文档
      • 控制中心
      • 备案
      • 管理中心

      C语言反汇编 - 流程控制与循环结构

      首页 知识中心 软件开发 文章详情页

      C语言反汇编 - 流程控制与循环结构

      2024-06-13 08:07:37 阅读次数:39

      C语言,循环,语句

      反汇编(Disassembly) 即把目标二进制机器码转为汇编代码的过程,该技术常用于软件破解、外挂技术、病毒分析、逆向工程、软件汉化等领域,学习和理解反汇编对软件调试、系统漏洞挖掘、内核原理及理解高级语言代码都有相当大的帮助,软件一切神秘的运行机制全在反汇编代码里面。

      IF-单条件分支语句: 单分支结构配合and与or实现的验证.

      #include <stdio.h>
      
      int main(int argc, char* argv[])
      {
      	int x = 10, y = 20, z = 30;
      	if (x >= y)
      	{
      		printf("x >=y");
      	}
      	else if (z >= x && z >= y)
      	{
      		printf("z>=x and z>=y");
      	}
      	return 0;
      }
      
      004113DE | C745 F8 0A000000         | mov dword ptr ss:[ebp-0x8],0xA              | x = 10
      004113E5 | C745 EC 14000000         | mov dword ptr ss:[ebp-0x14],0x14            | y = 20
      004113EC | C745 E0 1E000000         | mov dword ptr ss:[ebp-0x20],0x1E            | z = 30
      004113F3 | 8B45 F8                  | mov eax,dword ptr ss:[ebp-0x8]              | eax = 10
      004113F6 | 3B45 EC                  | cmp eax,dword ptr ss:[ebp-0x14]             | cmp 10,20 => 10-20
      004113F9 | 7C 19                    | jl 0x411414                                 | 上方表达式10小于20则跳 (第一个表达式)
      004113FB | 8BF4                     | mov esi,esp                                 | main.c:8, esi:__enc$textbss$end+109
      004113FD | 68 58584100              | push consoleapplication1.415858             | 415858:"x >=y"
      00411402 | FF15 14914100            | call dword ptr ds:[<&printf>]               |
      00411408 | 83C4 04                  | add esp,0x4                                 |
      0041140B | 3BF4                     | cmp esi,esp                                 | esi:__enc$textbss$end+109
      0041140D | E8 24FDFFFF              | call 0x411136                               |
      00411412 | EB 27                    | jmp 0x41143B                                |
      00411414 | 8B45 E0                  | mov eax,dword ptr ss:[ebp-0x20]             | eax = 30
      00411417 | 3B45 F8                  | cmp eax,dword ptr ss:[ebp-0x8]              | cmp 30,10 => 30-10
      0041141A | 7C 1F                    | jl 0x41143B                                 | 上方表达式 30>10 则jl不跳 (第二个表达式)
      0041141C | 8B45 E0                  | mov eax,dword ptr ss:[ebp-0x20]             | eax = 30
      0041141F | 3B45 EC                  | cmp eax,dword ptr ss:[ebp-0x14]             | cmp 30,20 => 30>20
      00411422 | 7C 17                    | jl 0x41143B                                 | 上方表达式 30>20 则jl不跳 (第二个表达式)
      00411424 | 8BF4                     | mov esi,esp                                 | main.c:12, esi:__enc$textbss$end+109
      00411426 | 68 60584100              | push consoleapplication1.415860             | 415860:"z>=x and z>=y"
      0041142B | FF15 14914100            | call dword ptr ds:[<&printf>]               | 最后打印输出字符串
      00411431 | 83C4 04                  | add esp,0x4                                 |
      

      if (z >= x && z >= y) 语句的表现形式

      C语言反汇编 - 流程控制与循环结构

      if (z >= x || z >= y) 稍微改变成或者,再来观察程序流程,两个结构对比,然后总结经验,或者与并且两个语句在实现上的异同点。

      C语言反汇编 - 流程控制与循环结构

      如果将代码编译为 Release 版本,你会发现if语句被优化没了,只保留了一个打印结果,这个优化还是很牛b的,整个结构都被重定义了。编译器认为你的判断没有任何意义,所以直接就给你干掉了,只保留了一个输出结果,这个输出结果是一定会被执行的,是一个定死的。

      C语言反汇编 - 流程控制与循环结构

      IF-嵌套条件分支:

      #include <stdio.h>
      
      int main(int argc, char* argv[])
      {
      	int x = 10, y = 20, z = 30;
      	if (x >= y || z >= x)
      	{
      		if (x <= z)
      		{
      			printf("x >=y or z>=x and x<=z");
      		}
      		else
      		{
      			printf("x >=y or z>=x and x>=z");
      		}
      	}
      	return 0;
      }
      
      004113DE | C745 F8 0A000000         | mov dword ptr ss:[ebp-0x8],0xA              | 0xA = 10
      004113E5 | C745 EC 14000000         | mov dword ptr ss:[ebp-0x14],0x14            | 0x14 = 20
      004113EC | C745 E0 1E000000         | mov dword ptr ss:[ebp-0x20],0x1E            | 0x1E = 30
      004113F3 | 8B45 F8                  | mov eax,dword ptr ss:[ebp-0x8]              | eax = 10
      004113F6 | 3B45 EC                  | cmp eax,dword ptr ss:[ebp-0x14]             | cmp eax,20 => 10-20
      004113F9 | 7D 08                    | jge 0x411403                                | 比较不成立,则不跳
      004113FB | 8B45 E0                  | mov eax,dword ptr ss:[ebp-0x20]             | eax = 30
      004113FE | 3B45 F8                  | cmp eax,dword ptr ss:[ebp-0x8]              | cpm eax,10 => 30-10
      00411401 | 7C 38                    | jl 0x41143B                                 | 比较不成立,则不跳
      00411403 | 8B45 F8                  | mov eax,dword ptr ss:[ebp-0x8]              | eax = 10
      00411406 | 3B45 E0                  | cmp eax,dword ptr ss:[ebp-0x20]             | cpm eax,30 => 10-30
      00411409 | 7F 19                    | jg 0x411424                                 | 10不大于30则不跳
      0041140B | 8BF4                     | mov esi,esp                                 | main.c:10
      0041140D | 68 58584100              | push consoleapplication1.415858             | 415858:"x >=y or z>=x and x<=z"
      00411412 | FF15 14914100            | call dword ptr ds:[<&printf>]               | 打印出结果
      00411418 | 83C4 04                  | add esp,0x4                                 |
      

      C语言反汇编 - 流程控制与循环结构

      WHILE-循环: x++ 是jge来操控,++x是jg

      #include <stdio.h>
      
      int main(int argc, char* argv[])
      {
      	int x = 0;
      	while (x <= 10)
      	{
      		printf("打印: %d\n", x);
      		x++;
      	}
      	return 0;
      }
      
      004113DE | C745 F8 00000000         | mov dword ptr ss:[ebp-0x8],0x0              | 0
      004113E5 | 837D F8 0A               | cmp dword ptr ss:[ebp-0x8],0xA              | cmp 0,10 =>
      004113E9 | 7F 26                    | jg 0x411411                                 | 0不大于10,则不跳
      004113EB | 8BF4                     | mov esi,esp                                 | main.c:8
      004113ED | 8B45 F8                  | mov eax,dword ptr ss:[ebp-0x8]              | eax = 0
      004113F0 | 50                       | push eax                                    |
      004113F1 | 68 58584100              | push consoleapplication1.415858             | 415858:"打印: %d\n"
      004113F6 | FF15 14914100            | call dword ptr ds:[<&printf>]               | 每次循环打印
      004113FC | 83C4 08                  | add esp,0x8                                 |
      004113FF | 3BF4                     | cmp esi,esp                                 |
      00411401 | E8 30FDFFFF              | call 0x411136                               | 微软堆栈检测器
      00411406 | 8B45 F8                  | mov eax,dword ptr ss:[ebp-0x8]              | 取出eax里面的值
      00411409 | 83C0 01                  | add eax,0x1                                 | 每次递增1
      0041140C | 8945 F8                  | mov dword ptr ss:[ebp-0x8],eax              |
      0041140F | EB D4                    | jmp 0x4113E5                                | main.c:10
      00411411 | 33C0                     | xor eax,eax                                 | main.c:11
      

      C语言反汇编 - 流程控制与循环结构

      在此基础上稍微增加难度,在while循环内部判断x是否能被2整除.

      #include <stdio.h>
      
      int main(int argc, char* argv[])
      {
      	int x = 0;
      	while (x <= 10)
      	{
      		printf("这是第: %d 次循环 \n", x+1);
      		if (x % 2 == 0)
      			printf("--> %d 次循环符合条件\n", x+1);
      		x++;
      	}
      	return 0;
      }
      
      004113DE | C745 F8 00000000         | mov dword ptr ss:[ebp-0x8],0x0            | 0
      004113E5 | 837D F8 0A               | cmp dword ptr ss:[ebp-0x8],0xA            | cmp 0,0xA => 循环10次
      004113E9 | 7F 5A                    | jg 0x411445                               | 0大于10则跳到结束
      004113EB | 8B45 F8                  | mov eax,dword ptr ss:[ebp-0x8]            | 取出循环计数
      004113EE | 83C0 01                  | add eax,0x1                               | 在此基础上+1
      004113F1 | 8BF4                     | mov esi,esp                               |
      004113F3 | 50                       | push eax                                  | 压入堆栈
      004113F4 | 68 58584100              | push consoleapplication1.415858           | 415858:"这是第: %d 次循环 \n"
      004113F9 | FF15 14914100            | call dword ptr ds:[<&printf>]             | 输出结果
      004113FF | 83C4 08                  | add esp,0x8                               | 堆栈恢复
      00411402 | 3BF4                     | cmp esi,esp                               |
      00411404 | E8 2DFDFFFF              | call 0x411136                             |
      00411409 | 8B45 F8                  | mov eax,dword ptr ss:[ebp-0x8]            | main.c:9
      0041140C | 25 01000080              | and eax,0x80000001                        | 取出循环计数,并验证是否%2=0
      00411411 | 79 05                    | jns 0x411418                              |
      00411413 | 48                       | dec eax                                   |
      00411414 | 83C8 FE                  | or eax,0xFFFFFFFE                         |
      00411417 | 40                       | inc eax                                   |
      00411418 | 85C0                     | test eax,eax                              | 比较eax是否为0
      0041141A | 75 1E                    | jne 0x41143A                              |
      0041141C | 8B45 F8                  | mov eax,dword ptr ss:[ebp-0x8]            | main.c:10
      0041141F | 83C0 01                  | add eax,0x1                               |
      00411422 | 8BF4                     | mov esi,esp                               |
      00411424 | 50                       | push eax                                  |
      00411425 | 68 70584100              | push consoleapplication1.415870           | 415870:"--> %d 次循环符合条件\n"
      0041142A | FF15 14914100            | call dword ptr ds:[<&printf>]             |
      00411430 | 83C4 08                  | add esp,0x8                               |
      00411433 | 3BF4                     | cmp esi,esp                               |
      00411435 | E8 FCFCFFFF              | call 0x411136                             |
      0041143A | 8B45 F8                  | mov eax,dword ptr ss:[ebp-0x8]            | main.c:11
      0041143D | 83C0 01                  | add eax,0x1                               |
      00411440 | 8945 F8                  | mov dword ptr ss:[ebp-0x8],eax            |
      00411443 | EB A0                    | jmp 0x4113E5                              | main.c:12
      00411445 | 33C0                     | xor eax,eax                               | main.c:13
      

      C语言反汇编 - 流程控制与循环结构

      继续修改源代码,增加双层循环,实现嵌套wihle循环.

      #include <stdio.h>
      
      int main(int argc, char* argv[])
      {
      	int x = 0, y = 0, z =0 ;
      	while (x <= 10)
      	{
      		while (y <= 5)
      		{
      			z = x + y;
      			if (z %2==0)
      				printf("外层循环: %d 内层循环: %d \n", x, y);
      			y = y + 1;
      		}
      		x = x + 1;
      	}
      	return 0;
      }
      
      004113DE | C745 F8 00000000         | mov dword ptr ss:[ebp-0x8],0x0            | x
      004113E5 | C745 EC 00000000         | mov dword ptr ss:[ebp-0x14],0x0           | y
      004113EC | C745 E0 00000000         | mov dword ptr ss:[ebp-0x20],0x0           | z
      004113F3 | 837D F8 0A               | cmp dword ptr ss:[ebp-0x8],0xA            | 定义外层循环,总共循环10次
      004113F7 | 7F 57                    | jg 0x411450                               |
      004113F9 | 837D EC 05               | cmp dword ptr ss:[ebp-0x14],0x5           | 定义内存循环,总共循环5次
      004113FD | 7F 46                    | jg 0x411445                               |
      004113FF | 8B45 F8                  | mov eax,dword ptr ss:[ebp-0x8]            | eax = x
      00411402 | 0345 EC                  | add eax,dword ptr ss:[ebp-0x14]           | add x,y
      00411405 | 8945 E0                  | mov dword ptr ss:[ebp-0x20],eax           | mov z = x+y
      00411408 | 8B45 E0                  | mov eax,dword ptr ss:[ebp-0x20]           | main.c:11
      0041140B | 25 01000080              | and eax,0x80000001                        | 取出z的值
      00411410 | 79 05                    | jns 0x411417                              |
      00411412 | 48                       | dec eax                                   |
      00411413 | 83C8 FE                  | or eax,0xFFFFFFFE                         |
      00411416 | 40                       | inc eax                                   |
      00411417 | 85C0                     | test eax,eax                              | 取出z的值,判断是否%2==0
      00411419 | 75 1F                    | jne 0x41143A                              |
      0041141B | 8BF4                     | mov esi,esp                               | main.c:12
      0041141D | 8B45 EC                  | mov eax,dword ptr ss:[ebp-0x14]           |
      00411420 | 50                       | push eax                                  |
      00411421 | 8B4D F8                  | mov ecx,dword ptr ss:[ebp-0x8]            |
      00411424 | 51                       | push ecx                                  |
      00411425 | 68 58584100              | push consoleapplication1.415858           | 415858:"外层循环: %d 内层循环: %d \n"
      0041142A | FF15 14914100            | call dword ptr ds:[<&printf>]             |
      00411430 | 83C4 0C                  | add esp,0xC                               |
      00411433 | 3BF4                     | cmp esi,esp                               |
      00411435 | E8 FCFCFFFF              | call 0x411136                             |
      0041143A | 8B45 EC                  | mov eax,dword ptr ss:[ebp-0x14]           | main.c:13
      0041143D | 83C0 01                  | add eax,0x1                               |
      00411440 | 8945 EC                  | mov dword ptr ss:[ebp-0x14],eax           |
      00411443 | EB B4                    | jmp 0x4113F9                              | 无条件跳转到内层循环
      00411445 | 8B45 F8                  | mov eax,dword ptr ss:[ebp-0x8]            | main.c:15
      00411448 | 83C0 01                  | add eax,0x1                               |
      0041144B | 8945 F8                  | mov dword ptr ss:[ebp-0x8],eax            |
      0041144E | EB A3                    | jmp 0x4113F3                              | 无条件跳转到外层循环
      00411450 | 33C0                     | xor eax,eax                               | main.c:17
      

      C语言反汇编 - 流程控制与循环结构

      这里的打印参数,很有趣,取值并压入两个参数,然后调用的printf.

      C语言反汇编 - 流程控制与循环结构

      DO-WHILE条件循环: 与while循环不同,do会先执行循环然后判断,如下代码反编译观察.

      #include <stdio.h>
      
      int main(int argc, char* argv[])
      {
      	int x = 0,y=0;
      	do
      	{
      		printf("外层do-while 循环: %d\n", x);
      		while (y <= 5)
      		{
      			printf("内层while 循环: %d\n", y);
      			y = y + 1;
      		}
      		x = x + 1;
      	} while (x <= 10);
      	return 0;
      }
      

      如下反汇编代码可以观察到代码结构,C语言在实现while语句与do-while语句的异同点,while语句是先判断然后才会进入循环体,而do-while则是先执行循环体内部的东西,最后补一刀来判断是否满足条件.

      004113DE | C745 F8 00000000         | mov dword ptr ss:[ebp-0x8],0x0            | x
      004113E5 | C745 EC 00000000         | mov dword ptr ss:[ebp-0x14],0x0           | y
      004113EC | 8BF4                     | mov esi,esp                               | main.c:8
      004113EE | 8B45 F8                  | mov eax,dword ptr ss:[ebp-0x8]            | mov eax,0
      004113F1 | 50                       | push eax                                  |
      004113F2 | 68 58584100              | push consoleapplication1.415858           | 415858:"外层do-while 循环: %d\n"
      004113F7 | FF15 14914100            | call dword ptr ds:[<&printf>]             |
      004113FD | 83C4 08                  | add esp,0x8                               |
      00411400 | 3BF4                     | cmp esi,esp                               |
      00411402 | E8 2FFDFFFF              | call 0x411136                             |
      00411407 | 837D EC 05               | cmp dword ptr ss:[ebp-0x14],0x5           | 进入内层循环
      0041140B | 7F 26                    | jg 0x411433                               | 直到条件大于5则退出
      0041140D | 8BF4                     | mov esi,esp                               | main.c:11
      0041140F | 8B45 EC                  | mov eax,dword ptr ss:[ebp-0x14]           |
      00411412 | 50                       | push eax                                  |
      00411413 | 68 74584100              | push consoleapplication1.415874           | 415874:"内层while 循环: %d\n"
      00411418 | FF15 14914100            | call dword ptr ds:[<&printf>]             |
      0041141E | 83C4 08                  | add esp,0x8                               |
      00411421 | 3BF4                     | cmp esi,esp                               |
      00411423 | E8 0EFDFFFF              | call 0x411136                             |
      00411428 | 8B45 EC                  | mov eax,dword ptr ss:[ebp-0x14]           | main.c:12
      0041142B | 83C0 01                  | add eax,0x1                               | 每次递增
      0041142E | 8945 EC                  | mov dword ptr ss:[ebp-0x14],eax           |
      00411431 | EB D4                    | jmp 0x411407                              | main.c:13
      00411433 | 8B45 F8                  | mov eax,dword ptr ss:[ebp-0x8]            | main.c:14
      00411436 | 83C0 01                  | add eax,0x1                               |
      00411439 | 8945 F8                  | mov dword ptr ss:[ebp-0x8],eax            |
      0041143C | 837D F8 0A               | cmp dword ptr ss:[ebp-0x8],0xA            | 外层循环的比较
      00411440 | 7E AA                    | jle 0x4113EC                              | 小于则跳转
      00411442 | 33C0                     | xor eax,eax                               | main.c:16
      

      C语言反汇编 - 流程控制与循环结构

      FOR-条件循环:

      #include <stdio.h>
      
      int main(int argc, char* argv[])
      {
      	int x;
      	for (x = 0; x <= 10; x++)
      	{
      		printf("循环计数: %d\n", x);
      	}
      	return 0;
      }
      
      004113DE | C745 F8 00000000         | mov dword ptr ss:[ebp-0x8],0x0            | 初始化 x=0
      004113E5 | EB 09                    | jmp 0x4113F0                              | 跳转到比较语句处
      004113E7 | 8B45 F8                  | mov eax,dword ptr ss:[ebp-0x8]            |
      004113EA | 83C0 01                  | add eax,0x1                               | 每次递增x++
      004113ED | 8945 F8                  | mov dword ptr ss:[ebp-0x8],eax            |
      004113F0 | 837D F8 0A               | cmp dword ptr ss:[ebp-0x8],0xA            | 判断x是否为10 x<=10
      004113F4 | 7F 1D                    | jg 0x411413                               | 大于则跳转到结束
      004113F6 | 8BF4                     | mov esi,esp                               | main.c:8, esi:__enc$textbss$end+109
      004113F8 | 8B45 F8                  | mov eax,dword ptr ss:[ebp-0x8]            |
      004113FB | 50                       | push eax                                  | 压入当前循环次数,并打印
      004113FC | 68 58584100              | push consoleapplication1.415858           | 415858:"循环计数: %d\n"
      00411401 | FF15 14914100            | call dword ptr ds:[<&printf>]             |
      00411407 | 83C4 08                  | add esp,0x8                               |
      0041140A | 3BF4                     | cmp esi,esp                               | esi:__enc$textbss$end+109
      0041140C | E8 25FDFFFF              | call 0x411136                             |
      00411411 | EB D4                    | jmp 0x4113E7                              | 跳转到递增语句处
      00411413 | 33C0                     | xor eax,eax                               | main.c:10
      

      C语言反汇编 - 流程控制与循环结构

      接着实现多分支for循环,也就是循环内部嵌套循环,接下来通过一个9x9口诀表分析,观察汇编代码变化.

      #include <stdio.h>
      
      int main(int argc, char* argv[])
      {
      	int x,y;
      
      	for (x = 1; x <= 9; x++)
      	{
      		for (y = 1; y <= x; y++)
      		{
      			printf("%d*%d=%d\t", y, x, x*y);
      		}
      		printf("\n");
      	}
      	system("pause");
      	return 0;
      }
      
      004113DE | C745 F8 01000000         | mov dword ptr ss:[ebp-0x8],0x1            | x = 1
      004113E5 | EB 09                    | jmp 0x4113F0                              |
      004113E7 | 8B45 F8                  | mov eax,dword ptr ss:[ebp-0x8]            |
      004113EA | 83C0 01                  | add eax,0x1                               | 外层循环计数器
      004113ED | 8945 F8                  | mov dword ptr ss:[ebp-0x8],eax            |
      004113F0 | 837D F8 09               | cmp dword ptr ss:[ebp-0x8],0x9            | 比较外层循环x是否大于9
      004113F4 | 7F 5C                    | jg 0x411452                               |
      004113F6 | C745 EC 01000000         | mov dword ptr ss:[ebp-0x14],0x1           | y = 1
      004113FD | EB 09                    | jmp 0x411408                              |
      004113FF | 8B45 EC                  | mov eax,dword ptr ss:[ebp-0x14]           |
      00411402 | 83C0 01                  | add eax,0x1                               | 内层循环计数器递增
      00411405 | 8945 EC                  | mov dword ptr ss:[ebp-0x14],eax           |
      00411408 | 8B45 EC                  | mov eax,dword ptr ss:[ebp-0x14]           | y
      0041140B | 3B45 F8                  | cmp eax,dword ptr ss:[ebp-0x8]            | cmp y,x
      0041140E | 7F 29                    | jg 0x411439                               | 大于则跳
      00411410 | 8B45 F8                  | mov eax,dword ptr ss:[ebp-0x8]            | main.c:11
      00411413 | 0FAF45 EC                | imul eax,dword ptr ss:[ebp-0x14]          |
      00411417 | 8BF4                     | mov esi,esp                               |
      00411419 | 50                       | push eax                                  |
      0041141A | 8B4D F8                  | mov ecx,dword ptr ss:[ebp-0x8]            |
      0041141D | 51                       | push ecx                                  |
      0041141E | 8B55 EC                  | mov edx,dword ptr ss:[ebp-0x14]           |
      00411421 | 52                       | push edx                                  |
      00411422 | 68 58584100              | push consoleapplication1.415858           | 415858:"%d*%d=%d\t"
      00411427 | FF15 18914100            | call dword ptr ds:[<&printf>]             | 输出三个参数
      0041142D | 83C4 10                  | add esp,0x10                              |
      00411430 | 3BF4                     | cmp esi,esp                               |
      00411432 | E8 04FDFFFF              | call 0x41113B                             |
      00411437 | EB C6                    | jmp 0x4113FF                              | main.c:12
      00411439 | 8BF4                     | mov esi,esp                               | main.c:13
      0041143B | 68 64584100              | push consoleapplication1.415864           | 415864:L"\n"
      00411440 | FF15 18914100            | call dword ptr ds:[<&printf>]             | 外层循环增加换行
      00411446 | 83C4 04                  | add esp,0x4                               |
      00411449 | 3BF4                     | cmp esi,esp                               |
      0041144B | E8 EBFCFFFF              | call 0x41113B                             |
      00411450 | EB 95                    | jmp 0x4113E7                              | main.c:14
      00411452 | 68 68584100              | push consoleapplication1.415868           | main.c:15, 415868:"pause"==L"慰獵e"
      00411457 | E8 49FCFFFF              | call 0x4110A5                             |
      0041145C | 83C4 04                  | add esp,0x4                               |
      

      x64dbg 摘要

      C语言反汇编 - 流程控制与循环结构

      iDA 摘要

      C语言反汇编 - 流程控制与循环结构

      SWITCH-条件选择结构: 这个结构很有意思,还原它也不是太难,主要是该结构通过查表得到执行哪条语句,只要找到分支所对应的表格就能逆向出不同分支的作用.

      #include <stdio.h>
      
      int main(int argc, char* argv[])
      {
      	int x;
      	scanf("%d", &x);
      	switch (x)
      	{
      	case 0:
      		printf("case 0"); break;
      	case 1:
      		printf("case 1"); break;
      	case 2:
      		printf("case 2"); break;
      	case 3:
      		printf("case 3"); break;
      	default:
      		printf("none"); break;
      	}
      	return 0;
      }
      
      004113F9 | 8B45 F8                  | mov eax,dword ptr ss:[ebp-0x8]            | main.c:7
      004113FC | 8985 30FFFFFF            | mov dword ptr ss:[ebp-0xD0],eax           | 假设输入的是1
      00411402 | 83BD 30FFFFFF 03         | cmp dword ptr ss:[ebp-0xD0],0x3           | cmp 1,3
      00411409 | 77 71                    | ja 0x41147C                               | 高于则跳,跳到default
      0041140B | 8B8D 30FFFFFF            | mov ecx,dword ptr ss:[ebp-0xD0]           | ecx = 输入的分支数字,此处是1
      00411411 | FF248D D4144100          | jmp dword ptr ds:[ecx*4+<>]               | jmp 1*4 + 0x4114D4
      00411418 | 8BF4                     | mov esi,esp                               | main.c:10
      0041141A | 68 5C584100              | push consoleapplication1.41585C           | 41585C:"case 0"
      0041141F | FF15 18914100            | call dword ptr ds:[<&printf>]             |
      00411425 | 83C4 04                  | add esp,0x4                               |
      00411428 | 3BF4                     | cmp esi,esp                               |
      0041142A | E8 0CFDFFFF              | call 0x41113B                             |
      0041142F | EB 62                    | jmp 0x411493                              |
      00411431 | 8BF4                     | mov esi,esp                               | main.c:12
      00411433 | 68 64584100              | push consoleapplication1.415864           | 415864:"case 1"
      00411438 | FF15 18914100            | call dword ptr ds:[<&printf>]             |
      0041143E | 83C4 04                  | add esp,0x4                               |
      

      C语言反汇编 - 流程控制与循环结构

      代码中有三个主分支,一个默认分支,所以这里能看到每个分支所对应的物理地址。

      C语言反汇编 - 流程控制与循环结构

      x64dbg 会将其标注为红色。

      C语言反汇编 - 流程控制与循环结构

      ida 的分析则更加强大。

      C语言反汇编 - 流程控制与循环结构

      分析C++中异常处理

      异常处理是任何一门编程语言都存在的一个特性,同样C++也规定了异常处理的写法,但由于C++标准中并没有明确定义异常处理的实现流程,因此导致不同编译器厂商在实现异常处理时各有不同,我们将以VS2013编译器所生成的异常处理代码进行深入分析,其他编译器自行研究吧.

      下来手动注册一个异常处理函数

      #include <iostream>
      #include <Windows.h>
      
      using namespace std;
      
      LONG __stdcall MyException1(_EXCEPTION_POINTERS *Ecptpoints)
      {
      	printf("发生异常,触发异常处理\n");
      	return 0;
      }
      
      int main(int argc, char* argv[])
      {
      	SetUnhandledExceptionFilter(MyException1); //设置异常的回调函数
      	int *ptr = 0;
      	*ptr = 1;
      	system("pause");
      	return 0;
      }
      
      #include <iostream>
      #include <Windows.h>
      
      using namespace std;
      
      int main(int argc, char* argv[])
      {
      	try
      	{
      		throw -1; //抛出int类型异常
      	}
      	catch (int e)
      	{
      		printf("抛出了int类型异常. \n");
      	}
      	catch (float e)
      	{
      		printf("抛出了float类型异常. \n");
      	}
      	return 0;
      }
      
      00415220 | 55                       | push ebp                               | main.cpp:7
      00415221 | 8BEC                     | mov ebp,esp                            |
      00415223 | 6A FF                    | push 0xFFFFFFFF                        |
      00415225 | 68 E0904100              | push <__ehhandler$_main>               | 压入异常回调函数
      0041522A | 64:A1 00000000           | mov eax,dword ptr fs:[0]               |
      00415230 | 50                       | push eax                               |
      00415231 | 64:8925 00000000         | mov dword ptr fs:[0],esp               | 注册异常回调处理函数
      00415238 | 51                       | push ecx                               | ecx:"榈K"
      00415239 | 81EC E4000000            | sub esp,0xE4                           |
      0041523F | 53                       | push ebx                               |
      00415240 | 56                       | push esi                               | esi:"榈K"
      00415241 | 57                       | push edi                               | edi:"榈K"
      00415242 | 8DBD 0CFFFFFF            | lea edi,dword ptr ss:[ebp-0xF4]        |
      00415248 | B9 39000000              | mov ecx,0x39                           | ecx:"榈K", 39:'9'
      0041524D | B8 CCCCCCCC              | mov eax,0xCCCCCCCC                     |
      00415252 | F3:AB                    | rep stosd                              |
      00415254 | 8965 F0                  | mov dword ptr ss:[ebp-0x10],esp        |
      00415257 | C745 FC 00000000         | mov dword ptr ss:[ebp-0x4],0x0         | 设置异常编号
      0041525E | C785 10FFFFFF FFFFFFFF   | mov dword ptr ss:[ebp-0xF0],0xFFFFFFFF | main.cpp:10
      00415268 | 68 60E94100              | push <consoleapplication2.__TI1H>      | 压入异常结构
      0041526D | 8D85 10FFFFFF            | lea eax,dword ptr ss:[ebp-0xF0]        | 获取异常分配函数地址
      00415273 | 50                       | push eax                               |
      00415274 | E8 A3BFFFFF              | call 0x41121C                          | 调用异常分配函数
      00415279 | 8BF4                     | mov esi,esp                            | main.cpp:14
      0041527B | 68 6CCC4100              | push consoleapplication2.41CC6C        | 41CC6C:"抛出了int类型异常. \n"
      00415280 | FF15 80014200            | call dword ptr ds:[<&printf>]          |
      00415286 | 83C4 04                  | add esp,0x4                            |
      
      版权声明:本文内容来自第三方投稿或授权转载,原文地址:https://my.oschina.net/lyshark/blog/5550742,作者:LyShark,版权归原作者所有。本网站转在其作品的目的在于传递更多信息,不拥有版权,亦不承担相应法律责任。如因作品内容、版权等问题需要同本网站联系,请发邮件至ctyunbbs@chinatelecom.cn沟通。

      上一篇:window.onload不能正常执行

      下一篇:python语句如何换行和字符串太长如何换行

      相关文章

      2025-05-14 10:03:13

      【Mybatis】-防止SQL注入

      【Mybatis】-防止SQL注入

      2025-05-14 10:03:13
      SQL , 执行 , 日志 , 注入 , 缓存 , 编译 , 语句
      2025-05-14 10:02:58

      30天拿下Rust之语法大全

      Rust作为一种系统编程语言,近年来在开发者社区中逐渐崭露头角。其独特的所有权系统和内存安全特性,使得Rust在高性能、并发编程领域具有显著优势。

      2025-05-14 10:02:58
      Rust , 代码 , 关键字 , 声明 , 循环 , 注释 , 类型
      2025-05-14 10:02:58

      30天拿下Rust之函数详解

      在Rust中,函数是程序的基本构建块,是代码复用的基本单位,用于封装一系列执行特定操作和计算的语句。函数是可重用的代码片段,可以接受输入参数并产生输出。通过合理使用函数,可以提高代码的可读性、可维护性和可重用性。

      2025-05-14 10:02:58
      Rust , 函数 , 参数 , 表达式 , 语句 , 返回 , 返回值
      2025-05-14 09:51:15

      python 判断for循环最后一次

      在Python中,通常我们不会直接判断for循环是否正在执行最后一次迭代,因为Python的for循环是基于可迭代对象的,它不知道也不关心迭代的内部状态(比如当前是第几次迭代)。但是,我们可以使用一些技巧来间接地实现这个需求。

      2025-05-14 09:51:15
      len , 对象 , 循环 , 迭代
      2025-05-14 09:51:15

      java循环创建对象内存溢出怎么解决

      在Java中,如果在循环中不当地创建大量对象而不及时释放内存,很容易导致内存溢出(OutOfMemoryError)。

      2025-05-14 09:51:15
      内存 , 占用 , 对象 , 引用 , 循环 , 次数 , 溢出
      2025-05-13 09:53:23

      一个python 程序执行顺序

      一个python 程序执行顺序

      2025-05-13 09:53:23
      Python , 代码 , 函数 , 循环 , 执行 , 语句
      2025-05-13 09:53:13

      mysql 存储函数及调用

      在MySQL中,存储函数(Stored Function)是一种在数据库中定义的特殊类型的函数,它可以从一个或多个参数返回一个值。存储函数在数据库层面上封装了复杂的SQL逻辑,使得在应用程序中调用时更加简单和高效。

      2025-05-13 09:53:13
      MySQL , 函数 , 存储 , 示例 , 触发器 , 语句 , 调用
      2025-05-13 09:53:13

      计算机小白的成长历程——函数递归与迭代

      计算机小白的成长历程——函数递归与迭代

      2025-05-13 09:53:13
      函数 , 循环 , 编写 , 迭代 , 递归
      2025-05-13 09:50:59

      DG搭建过程中备库执行活动复制时报错RMAN-01007、RMAN-01009

      DG搭建过程中备库执行活动复制时报错RMAN-01007、RMAN-01009

      2025-05-13 09:50:59
      RMAN , 客户端 , 语句
      2025-05-13 09:50:48

      查找正在执行的select以及dml语句的相关信息

      查找正在执行的select以及dml语句的相关信息

      2025-05-13 09:50:48
      select , session , sql , SQL , 语句
      查看更多
      推荐标签

      作者介绍

      天翼云小翼
      天翼云用户

      文章

      33561

      阅读量

      5234283

      查看更多

      最新文章

      30天拿下Rust之语法大全

      2025-05-14 10:02:58

      一个python 程序执行顺序

      2025-05-13 09:53:23

      DS初阶:循环队列的实现

      2025-05-08 09:04:49

      C语言-------冒泡排序,步步分解

      2025-05-08 09:03:07

      基础—SQL—DCL(数据控制语言)小结

      2025-05-07 09:09:52

      springboot系列教程(六):Jdbc与多数据源(含源码)

      2025-05-07 09:08:42

      查看更多

      热门文章

      C语言标识符

      2023-03-15 09:28:04

      C语言大一期末复习基础知识点

      2023-05-17 06:39:43

      C#编程-29:循环访问目录树

      2023-03-16 08:39:34

      循环三要素 编程 230211

      2023-04-07 06:43:28

      JavaScript-while 和 do while 如何选择

      2023-05-16 09:43:58

      【Java面试小短文】Spring 如何解决循环依赖?

      2023-06-14 09:11:57

      查看更多

      热门标签

      java Java python 编程开发 代码 开发语言 算法 线程 Python html 数组 C++ 元素 javascript c++
      查看更多

      相关产品

      弹性云主机

      随时自助获取、弹性伸缩的云服务器资源

      天翼云电脑(公众版)

      便捷、安全、高效的云电脑服务

      对象存储

      高品质、低成本的云上存储服务

      云硬盘

      为云上计算资源提供持久性块存储

      查看更多

      随机文章

      【数据结构】——拿捏 栈和队列

      C语言解题 || 调整数列

      Java 入门指南

      python中顺序结构

      输入十个数统计并统计正数负数和零的个数

      C语言简易程序设计————25、求解数列前20项之和

      • 7*24小时售后
      • 无忧退款
      • 免费备案
      • 专家服务
      售前咨询热线
      400-810-9889转1
      关注天翼云
      • 旗舰店
      • 天翼云APP
      • 天翼云微信公众号
      服务与支持
      • 备案中心
      • 售前咨询
      • 智能客服
      • 自助服务
      • 工单管理
      • 客户公告
      • 涉诈举报
      账户管理
      • 管理中心
      • 订单管理
      • 余额管理
      • 发票管理
      • 充值汇款
      • 续费管理
      快速入口
      • 天翼云旗舰店
      • 文档中心
      • 最新活动
      • 免费试用
      • 信任中心
      • 天翼云学堂
      云网生态
      • 甄选商城
      • 渠道合作
      • 云市场合作
      了解天翼云
      • 关于天翼云
      • 天翼云APP
      • 服务案例
      • 新闻资讯
      • 联系我们
      热门产品
      • 云电脑
      • 弹性云主机
      • 云电脑政企版
      • 天翼云手机
      • 云数据库
      • 对象存储
      • 云硬盘
      • Web应用防火墙
      • 服务器安全卫士
      • CDN加速
      热门推荐
      • 云服务备份
      • 边缘安全加速平台
      • 全站加速
      • 安全加速
      • 云服务器
      • 云主机
      • 智能边缘云
      • 应用编排服务
      • 微服务引擎
      • 共享流量包
      更多推荐
      • web应用防火墙
      • 密钥管理
      • 等保咨询
      • 安全专区
      • 应用运维管理
      • 云日志服务
      • 文档数据库服务
      • 云搜索服务
      • 数据湖探索
      • 数据仓库服务
      友情链接
      • 中国电信集团
      • 189邮箱
      • 天翼企业云盘
      • 天翼云盘
      ©2025 天翼云科技有限公司版权所有 增值电信业务经营许可证A2.B1.B2-20090001
      公司地址:北京市东城区青龙胡同甲1号、3号2幢2层205-32室
      • 用户协议
      • 隐私政策
      • 个人信息保护
      • 法律声明
      备案 京公网安备11010802043424号 京ICP备 2021034386号