06 | 指令跳转:原来if...else就是goto

不只有 int a = 1 总是要用到 if…else 、while 和 for 还有函数或者过程调用。

CPU 执行的也不只是一条指令,因为有 if…else、for 这样的条件和循环存在,指令不会一路平铺直叙地执行下去。程序是怎么被分解成一条条指令来执行的?

CPU是如何执行指令的?

程序员只要知道,代码变指令后,一条一条顺序执行就可以。

CPU 是一堆寄存器组成,寄存器由多个触发器(Flip-Flop)或者锁存器(Latches)组成简单电路,两种不同原理的数字电路组成的逻辑门。

N 个触发器或者锁存器,就可组成一个 N 位(Bit)的寄存器,能保存 N 位数据。 64 位 Intel 服务器,寄存器就是 64 位的。

一个 CPU 会有很多种不同功能寄存器。三种特殊的:

(1)PC 寄存器(Program Counter Register),也叫指令地址寄存器(Instruction Address Register)。存放下一条要执行的计算机令的内存地址

(2)指令寄存器(Instruction Register),存放当前正在执行指令。

(3)条件码寄存器(Status Register),一个个标记位(Flag),存放 CPU 进行算术或者逻辑计算的结果。

(4)其他:整数浮点数向量、地址寄存器等等。有些可以存放数据,又能存放地址,就叫通用寄存器。

程序执行时,CPU 根据 PC 寄存器里的地址,从内存里面把需要执行的指令(连续保存)读取到指令寄存器里面执行,根据指令长度自增顺序读下一条

特殊指令,上一讲 J 类指令(跳转指令),会修改 PC 寄存器里面的地址值下一条要执行的指令就不是从内存里面顺序加载的了。使用 if…else 条件语句和 while/for 循环语句的原因。

二、从 if…else 来看程序的执行和跳转

包含 if…else 的简单程序。

rand 生成一个随机数 r,r 是 0/ 1。 r 是 0时,把变量 a 设成 1,不然就设成 2。

$ gcc -g -c  test.c

$ objdump -d -M  intel -S test.o

编译成汇编代码。忽略前后无关的代码,关注于这里的 if…else 条件判断语句:

r == 0 的条件判断,被编译成了 cmp 和 jne 两条指令

(一)cmp 指令:比较两个操作数值,比较结果,存入条件码寄存器

    (1)DWORD PTR :操作数据类型是 32 位整数

    (2)[rbp-0x4] :寄存器的地址。

    (3)第一个操作数:寄存器里拿到的变量 r 的值第二个操作数 0x0 就是我们设定的常量 0 16 进制表示

    r == 0,就把零标志条件码(对应的条件码是 ZF,Zero Flag)设置为 1。除了零标志之外,Intel 的 CPU 下还有进位标志(CF,Carry Flag)、符号标志(SF,Sign Flag)以及溢出标志(OF,Overflow Flag),用在不同的判断条件下。

cmp 指令执行完成之后,PC 寄存器会自动自增,开始执行下一条 jne 的指令。

 (二)、 jne 指令,是 jump if not

equal :查看对应的零标志位。= 0,跳转4a (对应汇编代码行号, else 条件里的第一条指令)。跳转时(mov 指令),PC 寄存器:不再是自增变成下一条指令的地址,而是被直接设置成 4a 地址,指令寄存器执行4a 地址。

mov 指令:(1)和 cmp 一样, 32 位整型寄存器地址,对应的 2 的 16 进制值 0x2。

(2)4a这条指令:把 2 设置到对应的寄存器里(赋值),PC 寄存器里的值自增,执行下一条 mov 指令。

(3)51这条指令:占位符,没实际作用,第一个操作数 eax:寄存器, 0x0:16 进制的 0 。

 if 条件,如满足,

赋值的 mov 指令(41)执行完, jmp无条件跳转 51。 main 函数没有设定返回值,而 mov eax, 0x0其实就是给 main 函数生成了一个默认的为 0 的返回值到累加器里面。if 条件里面的内容执行完成之后(和 else 一样)跳转到这里,。

读取打孔卡机器顺序一段一段读取指令,执行。有跳转地址,比如往后跳 10 个指令,机器自动将卡片带往后移动 10 个指令的位置再执行指令。也能向前移动, while/for 循环实现原理。

如何通过 if…else goto 来实现循环?

 for 循环的程序。三次之后,i>=3,就会跳出循环。

循环用 1e 地址上 cmp 比较指令,和紧接着的 jle 条件跳转指令来实现的。差别: jle 跳转的地址,在这条指令之前的地址 14,而非 if…else 编译出来的跳转指令之后。条件满足,PC 寄存器会把指令地址设置到之前执行过的指令位置,重新执行,直到条件不满足,执行 jle 之后的指令,循环才结束。

如果你看一长条打孔卡的话,就会看到卡片往后移动一段,执行了之后,又反向移动,去重新执行前面的指令。

jle 和 jmp 指令,有点像 goto 命令,指定跳转位置。虽反对使用 goto,但实际机器指令层面 if…else, for/while ,都是用和 goto 相同方式实现。

总结延伸

这一节,在单条指令的基础上,学习了多条指令,怎么样一条条被执行。 PC 寄存器自增的方式顺序执行条件码寄存器记录下当前执行指令的条件判断状态,然后通过跳转指令读取对应的条件码修改 PC 寄存器内的下一条指令的地址,最终实现 if…else 以及 for/while 这样的程序控制流程。类似 goto 语句。

硬件层面实现goto 语句,要保存下一条指令地址,以及当前正要执行指令的 PC 寄存器、指令寄存器,条件码寄存器,保留条件判断的状态。三个寄存器就可以实现。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,384评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,845评论 3 391
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,148评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,640评论 1 290
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,731评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,712评论 1 294
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,703评论 3 415
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,473评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,915评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,227评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,384评论 1 345
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,063评论 5 340
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,706评论 3 324
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,302评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,531评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,321评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,248评论 2 352

推荐阅读更多精彩内容

  • 指令系统 程序功能:求两个数据之和并输出 运行结果:sum is 25 基本概念: 指令:是计算机硬件能够直接理解...
    我可能是个假开发阅读 4,989评论 0 5
  • 个人学习批处理的初衷来源于实际工作;在某个迭代版本有个BS(安卓手游模拟器)大需求,从而在测试过程中就重复涉及到...
    Luckykailiu阅读 4,713评论 0 11
  • 计算机系统漫游 代码从文本到可执行文件的过程(c语言示例):预处理阶段,处理 #inlcude , #defin...
    willdimagine阅读 3,579评论 0 5
  • 算术和逻辑指令ADC : 带进位的加法(Addition with Carry)ADC{条件}{S} <dest...
    luffier阅读 3,752评论 0 3
  • 计算机通过执行指令序列来使机器得以工作,所以对于每一系列的计算机都有指定的一组指令集供计算机使用,这组指令...
    未来科技工作室阅读 7,984评论 1 10