408王道计算机组成原理强化——指令系统及大题解构(下)

简介: 408王道计算机组成原理强化——指令系统及大题解构

2.x86

2.1.运算、逻辑类指令0deaa7dc41774167bf62536f8538cce0.png

有符号数和无符号数在形式上可能有差别,但是都会带有每个指令的主体部分

2.2.分支结构cd737276082a4ea6b62f3ee2ba68522e.png

1.CMP交由ALU运行,并由ALU产生标志位,再通过标志位进行判断和相应操作

2.偏移量的单位可能是字节,也可能是指令字长(往前/往后跳多少条指令,RISC):

jmp -10;        PC = AE86

①以字节为单位:PC = AE86 - 10

②以指令字长为单位(RISC,定长指令4B):PC = AE86 - 10 * 4

2.3.循环结构7e13eba7249345489adc499ef3ffb7da.png

1.条件转移指令:先实现循环结构主体相对应的机器指令,再在这些指令后,添加cmp和jxx指令,即满足条件的话,则回到循环主体指令对应的开始处

2.loop:循环到label位置

2.4.函数调用/返回d57833fe133a4e64bbafc2eba2829fa3.png

1.(1)call(调用一个函数):

①压入调用函数的所使用的参数(程序员通过push指令手动实现)

②执行Call指令

③压入返回地址,即当前的PC值(CALL指令实现)(存放返回地址的地址是a栈的栈顶)

④压入a的栈底指针,即ebp的值(程序员通过push指令手动实现)(存放a的栈底地址的地址是b栈的栈底)(每个函数刚开始执行的时都要执行push ebp,即将上一层的栈底指针压入栈中f03028a5413a4442ad0ca033048eb4dc.png

(该函数刚开始便执行push ebp,将上一层的栈底地址压入函数调用栈中)

⑤修改ESP寄存器的值为b函数的栈顶,即ESP指向④;修改EBP为b函数的栈底,即EBP指向③(CALL指令实现)(esp寄存器和ebp寄存器分别只有一个,故执行b函数时保存的是b函数的相关值)

存放返回地址的地址属于a栈,存放a的栈底地址的地址属于b栈)

132161ee07464cd4aef50ea4c7415e49.png

(2)ret(这次调用返回):CALL的逆向操作

①通过逐一弹出函调用栈数的栈顶元素的方式(pop)回收该函数的函数调用栈空间,每次esp弹出后都会 - 1

当弹出到ebp所指向的位置是该函数的栈底(该处存放上一层函数的栈底地址)时(ebp和esp此时都指向该栈的栈底)

A.弹出栈顶元素,并修改ebp寄存器为上一层函数的栈底地址(ebp指向上一层函数的栈底),esp弹出自动 - 1,即esp指向上一层函数的栈顶元素(该地址存放的是上一层函数的返回地址,即调用函数结束后,返回上一层函数继续执行的下一条指令的地址)

B.继续弹出栈顶元素,并将PC的值修改为上层函数的返回地址

2.设main函数调用a函数,a函数调用b函数:则函数调用栈中

①最底层为main函数

②a函数在main函数的上一层:存放a函数中的变量、返回地址(b函数执行结束,返回a函数后执行的下一条指令的地址;执行结束后,将PC的值修改为该地址)

③b函数在a函数的上一层:存放b函数中的变量、a函数的栈底地址的地址(函数b执行结束后

,ebp的值修改为该地址,作用是确定每个函数的地址范围)

即每个被调用函数需要记录:

①其函数结束,返回上一层函数后应该继续执行上一层函数的哪个指令,即返回地址

②上一层函数的栈底地址(存放该地址的地址作为自身函数的栈底,EBP指向该处)

3.①EBP(栈底指针)寄存器和ESP(栈顶指针)寄存器分别只有一个(函数调用和函数返回时ebp和esp都要进行修改)

②b函数在执行过程中,EBP指向b函数的栈底,ESP指向b函数的栈顶

③b函数执行结束,通过逐一弹出b函数的栈顶元素的方式(pop)回收b函数的函数调用栈空间(b函数的ESP在执行弹出栈顶元素操作时不断减1),直到b函数的ESP和EBP指向同一位置时,即到了b函数的栈底,且该位置存放a函数的栈底地址(a函数调用的b函数,即a函数是b函数的上一层函数);然后,EBP改为指向a栈底将EBP寄存器的值从b的栈底地址改为a的栈底地址),ESP则通过继续弹出栈顶元素的方式,就会从指向b的栈底 - 1,即ESP指向a的栈顶(a的栈顶此时存放的是返回地址,即b函数结束,返回a函数时应该继续执行的下条指令),将a的栈顶元素弹出并放入PC,即将下一条要执行的a函数的指令(即调用b函数指令的下一条指令)放入PC中b6dc9f0eccb246c6963ffe14f768f157.png

4.函数中声明一个局部变量的机器级指令实现是通过一个push指令将该变量压入栈中

5.函数使用当前函数的局部变量和上一层函数调用时使用的参数是通过对EBP进行偏移实现的

设每个地址的长度是4B,且高地址部分存放的是a栈,低地址部分存放的是b栈,函数a调用函数b,则在函数b的执行期间

ebp为b的栈底,存放的是a的栈底的地址

ebp + 4为返回地址,存放的是函数b执行结束返回函数a时,应该执行函数a的下一条指令的地址

ebp + 8开始为函数a调用函数b时传入的参数,属于a栈(+8即a2,+12即a1)

ebp - 4开始为函数b的局部变量,属于b栈(-4即b1,-8即b2)

7a039ef7359d439b8bec4626bbe83332.png

3.真题089760273c814046904c57ba1e0445c5.png

①第1行(push):每次循环调用该函数时,第一件事先将ebp寄存器的值(上一层函数的栈底地址)压入栈中

②第11行(cmp):将存放在ebp + 8地址的值(上一层函数调用该函数时所使用的的参数)和1对比

③第12行(jle):当第11行的cmp结果为真时,跳转到虚拟地址为0040 1035处执行,否则按顺序执行下一条指令

④第13行(mov):将存放在ebp + 8地址的值(上一层函数调用该函数时所使用的的参数)放入eax寄存器中

⑤第14行(sub):对eax寄存器的值减1(实现n-1)

⑥第15行(push):将eax寄存器的值压入函数调用栈中(调用函数时,传入该调用函数的参数要压入本函数的函数调用栈中)

⑦第16行(call):调用CALL函数,跳转虚拟地址为0040 1000H处执行指令(实现循环)

(1)f(10)将调用10次函数f1;执行第16行call指令时将会递归调用f1

(2)第12行jle是条件转移指令;第16行call、第20行jmp、第30行ret一定会使程序跳转执行

(3)第16行的CALL指令占用5个字节(E8 D6 FF FF FF),且该指令的地址为0040 1025H,则下一条指令的地址为0040 1025 + 5 = 0040 102AH

相对寻址方式是以PC寄存器中的值为基准进行偏移,PC中存放的是下一条指令的地址,则执行CALL指令时,PC中的内容是0040 102AH,要将下一条执行的指令回到f1处,则需将PC修改为0040 1000H,即偏移量0040 1000H - 0040 102A = -2AH

偏移量-2AH用补码表示为FF FF FF D6,而CALL指令的后4B为D6 FF FF FF,故采用小端存储

(4)f(13)的真值超过了32bit的int类型所能表示的范围,需要将返回值类型改为double

(5)当高n + 1位不全为0或者不全为1时,乘法就发生溢出;发生溢出时转为异常处理,则需要添加陷入指令

相关文章
408王道计算机组成原理强化——输入输出系统大题(I/O)
408王道计算机组成原理强化——输入输出系统大题(I/O)
377 1
408王道计算机组成原理强化——输入输出系统大题(I/O)
|
算法 网络虚拟化 内存技术
408王道计算机组成原理强化——存储系统大题
408王道计算机组成原理强化——存储系统大题(下)
2170 2
408王道计算机组成原理强化——存储系统大题
|
3月前
深挖计算机的根:汇编语言与计算机架构之间不可告人的秘密
【8月更文挑战第31天】本文深入探讨了汇编语言与计算机架构之间的重要联系。通过解析汇编语言的基本概念及其与硬件的直接映射关系,文章展示了它在计算机体系中的独特地位。以一个简单的“Hello, World!”汇编程序为例,详细说明了汇编语言如何操作底层硬件。尽管现代软件开发中较少使用汇编语言,但掌握它有助于理解计算机工作原理,对于性能优化和系统编程至关重要。
47 2
|
5月前
|
数据挖掘
计算机在生活中的作用
计算机在生活中的作用
104 0
|
5月前
|
存储 知识图谱
【计算机组成原理】指令系统&考研真题详解之拓展操作码!
也就是说 “其中三地址指令29”条这句话,完全可以翻译成“三地址这种类型的指令一共能有29种不同的可能性” 这样说就清晰多 因为这就意味着 我们需要用若干个字节 来表示这29种不同的可能性 然后又已知每一个字节位能表示的可能性是2种(0/1),那么我们想有多少个字节可以表示29种不同的可能呢?最少5种 (因为2的4次方=16<29),2^5=32>29,也就是说有32-29=3种可能性是不在三地址指令这种类型的指令集里面的,所以这3 种余出来的可能性要被利用 就在下一种 “二地址指令集”中利用到
73 0
|
6月前
|
JavaScript 前端开发 Java
关于对计算机发展史、冯诺依曼体系、CPU基本工作流程以及关于编程语言的简单认识
关于对计算机发展史、冯诺依曼体系、CPU基本工作流程以及关于编程语言的简单认识
|
JavaScript 前端开发 C语言
聊一聊|计算机函数
聊一聊|计算机函数
132 0
聊一聊|计算机函数
|
存储 Java Unix
程序员必知必会之计算机系统概论
程序员必知必会之计算机系统概论
97 0
|
编译器
408王道计算机组成原理强化——指令系统及大题解构(上)
408王道计算机组成原理强化——指令系统及大题解构
265 1
408王道计算机组成原理强化——指令系统及大题解构(上)
|
内存技术
408王道计算机组成原理强化——中央处理器及大题解构(上)
408王道计算机组成原理强化——中央处理器及大题解构
687 1
408王道计算机组成原理强化——中央处理器及大题解构(上)