(七)if/else就是goto
一、CPU如何执行指令
CPU上有数以亿计的晶体管组层的复杂电路,我们先不用管具体电路如何实现;逻辑上我们可以认为CPU由许多寄存器组成,而这些寄存器又由许多锁存器和触发器组成,N个锁存器或触发器就可以构成一个N位寄存器,例如64位CPU是指其寄存器是64位的。

CPU中有以下三种典型的寄存器,这里重点讲一下:
- PC寄存器:用来存放下一条要执行指令的存储地址;
- 指令寄存器:存放当前正在执行的指令;
- 条件寄存器:内部用一个标记位保存CPU算数运算或逻辑运算的结果;
程序执行时CPU不断依据PC寄存器的地址取出一条条指令交给指令寄存器执行,然后PC寄存器中指令地址不断根据指令长度递增,由此可知指令一般是顺序存放的,例外情况是遇到跳转指令会直接替换PC寄存器中的指令地址到指定地址。
二、以if/else看指令执行和跳转
示例代码:
// test.c
#include <time.h>
#include <stdlib.h>
int main()
{
srand(time(NULL));
int r = rand() % 2;
int a = 10;
if (r == 0)
{
a = 1;
} else {
a = 2;
}
编译结果:
if (r == 0)
3b: 83 7d fc 00 cmp DWORD PTR [rbp-0x4],0x0
3f: 75 09 jne 4a <main+0x4a>
{
a = 1;
41: c7 45 f8 01 00 00 00 mov DWORD PTR [rbp-0x8],0x1
48: eb 07 jmp 51 <main+0x51>
}
else
{
a = 2;
4a: c7 45 f8 02 00 00 00 mov DWORD PTR [rbp-0x8],0x2
51: b8 00 00 00 00 mov eax,0x0
}
分析:
- if判断被编译为 cmp和jne两条指令,rbp-0x4地址寄存器中的数和0进行比较将比较结果存入条件码寄存器,如果r为0,则将0标志条件码记为1;
- 接着顺序执行jne指令,jne 表示 jump not equal ,此时查看条件码寄存器,如果条件码寄存器值为0则直接将PC寄存器中下一条指令地址置为4a,进而跳转执行4a行指令;
- 末尾51行mov 命令 eax表示一个累加器,0x0实际是一个占位符,整个这条指令相当于为main方法生成了一个默认为0的返回值在累加器里面。
- 假若r为0,则程序会顺序执行完41后在48跳转到51
三、循环应该怎么干
示例代码:
int main()
{
int a = 0;
for (int i = 0; i < 3; i++)
{
a += i;
}
}
编译结果:
for (int i = 0; i < 3; i++)
b: c7 45 f8 00 00 00 00 mov DWORD PTR [rbp-0x8],0x0
12: eb 0a jmp 1e <main+0x1e>
{
a += i;
14: 8b 45 f8 mov eax,DWORD PTR [rbp-0x8]
17: 01 45 fc add DWORD PTR [rbp-0x4],eax
for (int i = 0; i < 3; i++)
1a: 83 45 f8 01 add DWORD PTR [rbp-0x8],0x1
1e: 83 7d f8 02 cmp DWORD PTR [rbp-0x8],0x2
22: 7e f0 jle 14 <main+0x14>
24: b8 00 00 00 00 mov eax,0x0
}
分析:
- b行为i赋初始值0,然后顺序执行跳转到1e行;
- 1e行 cmp 指令比较i的值与2
- 22行判断比较结果小鱼等于2则跳转回14行
- 直到jle条件不满足,顺序执行24在累加器中存入默认返回值0.
可见循环操作就是可以将指令执行未知“拨回”已经执行过的行;通过PC寄存器保存下一条要执行的指令、条件码寄存器保存条件运算结果、指令寄存器保存当前执行的指令再加上可以直接修改PC寄存器中下条指令的地址,就可以实现条件分支运算和循环。
(七)if/else就是goto的更多相关文章
- Go语言流程控制中的break,continue和goto(七)
break(跳出循环) break用于跳出整个循环,如下: func main() { ;i<;i++{ { break } fmt.Println(i) } } // 0 1 2 3 代码里只 ...
- apue第七章学习总结
apue第七章学习总结 1.main函数 程序是如何执行有关的c程序的? C程序总是从main函数开始执行.main函数的原型是 int main(int argc,char *argv[]); 其中 ...
- Linux就这个范儿 第15章 七种武器 linux 同步IO: sync、fsync与fdatasync Linux中的内存大页面huge page/large page David Cutler Linux读写内存数据的三种方式
Linux就这个范儿 第15章 七种武器 linux 同步IO: sync.fsync与fdatasync Linux中的内存大页面huge page/large page David Cut ...
- goto语句 switch语句
goto语句 #include <iostream> using namespace std; int main() { int i = 1; number: i++; std::cout ...
- 《学习OpenCV》练习题第四章第七题abc
题外话:一直是打算把这本书的全部课后编程题写完的,中间断了几个月,一直忙于其他事.现在开始补上. 这道题我不清楚我理解的题意是不是正确的,这道题可以练习用OpenCV实现透视变换(可以用于矫正在3维环 ...
- C primer plus 读书笔记第六章和第七章
这两章的标题是C控制语句:循环以及C控制语句:分支和跳转.之所以一起讲,是因为这两章内容都是讲控制语句. 第六章的第一段示例代码 /* summing.c --对用户输入的整数求和 */ #inclu ...
- perl5 第七章 控制结构
第七章 控制结构 by flamephoenix 一.条件判断二.循环: 1.while循环 2.until循环 3.for循环 4.针对列表(数组)每个元素的foreach循环 5. ...
- OpenGL ES着色器语言之语句和结构体(官方文档第六章)内建变量(官方文档第七、八章)
OpenGL ES着色器语言之语句和结构体(官方文档第六章) OpenGL ES着色器语言的程序块基本构成如下: 语句和声明 函数定义 选择(if-else) 迭代(for, while, do-wh ...
- Iptables详解七层过滤
<Iptables详解七层过滤> 一.防火墙简介 防火墙其实就是一个加固主机或网络安全的一个设备或者软件而已,通过防火墙可以隔离风险区域与安全区域的连接,同时不会妨碍风险区域的访问.当然需 ...
随机推荐
- Skip Lists: A Probabilistic Alternative to Balanced Trees 阅读笔记
论文地址:https://15721.courses.cs.cmu.edu/spring2018/papers/08-oltpindexes1/pugh-skiplists-cacm1990.pdf ...
- 对udp dns的思考2
上一篇文章写道了udp 使用reuseport 多线程编程!!! 但是有几个问题需要考虑一下: 之前hash使用sip sport dip dport为key, 很正常同一个客户端回hash到同一个s ...
- opencv 学习1 gui属性
1.图像 先定一个小目标学习两个个功能 1.学习怎样读入一副画像,以及如何保存一副图像 2.学习三个函数cv2.imread(), cv2.imshow() , cv2.imwrite() 1.1读入 ...
- Python_selenium案例:
selenium案例 #coding=utf-8 #select下拉框处理 from selenium import webdriver from selenium.webdriver.common. ...
- 学习搭建 Consul 服务发现与服务网格-有丰富的示例和图片
目录 第一部分:Consul 基础 1,Consul 介绍 2,安装 Consul Ubuntu/Debian 系统 Centos/RHEL 系统 检查安装 3,运行 Consul Agent 启动 ...
- 【原创】Linux虚拟化KVM-Qemu分析(六)之中断虚拟化
背景 Read the fucking source code! --By 鲁迅 A picture is worth a thousand words. --By 高尔基 说明: KVM版本:5.9 ...
- Linux 入侵痕迹清理技巧
清除history历史命令记录 vim ~/.bash_history //编辑history记录文件,删除部分不想被保存的历史命令 history -c //清除当前用户的history命令记录 H ...
- 企业级工作流解决方案(十五)--集成Abp和ng-alain--Abp其他改造
配置功能增强 Abp定义了各种配置接口,但是没有定义这些配置数据从哪里来,但是管理配置数据对于一个应用程序来说,是必不可少的一件事情. .net的配置数据管理,一般放在Web.config文件或者Ap ...
- Improving Commonsense Question Answering by Graph-based Iterative Retrieval over Multiple Knowledge Sources —— 基于多知识库迭代检索的常识问答系统
基于多知识库迭代检索的问答系统 论文地址 背景 常识问答任务需要引入外部知识来帮助模型更好地理解自然语言问题,现有的解决方案大都采用两阶段框架: 第一阶段 -- 从广泛的知识来源中找到与给定问题相关的 ...
- 从递归到memo到动态规划
//memo,记忆化搜索 class Solution { int[][] memo; public boolean wordBreak(String s, List<String& ...