理解计算机系统_程序的机器级表示(二):寄存器,操作数,数据传送,程序栈

news2024/10/9 10:25:10

前言

        以<深入理解计算机系统>(以下称“本书”)内容为基础,对程序的整个过程进行梳理。本书内容对整个计算机系统做了系统性导引,每部分内容都是单独的一门课.学习深度根据自己需要来定

引入

        本书第三章:程序的机器级表示内容的理解,这一章内容以汇编语言为主.汇编语言偏底层,用于系统级别的程序编写.如果不是做系统的,可以不用深入学习.理解汇编语言的关键是理解gcc指令,数据,寄存器,地址等概念.这些概念在C语言中也是很重要的,而且从汇编语言的角度会发现更多细节.

        这章可以作为学习C语言的辅助,明白C语言的运行机制.其中重点关注能优化代码的部分.

        本帖内容为3.4节访问信息

一.寄存器

        本书P119讲了寄存器的演化历史,和指令集历史同步.

        1>寄存器是干什么的?

         大致推导代码执行过程:源代码经编译汇编链接后,成为可执行文件并加载到内存中.可执行文件是十六进制组成的机器码,实际上是一条条的指令,交给CPU执行.

        每条指令有指令码和操作数.例如

movl $0x4050,%eax

         指令码由PC(程序计数器Program Counter)管理,存放着指令地址,执行完一条指令后,自动指向下一条指令的地址.CPU执行相应的指令,作为软件开发者可以不管CPU是怎么完成指令的,因为指令码提供了机器活动的抽象,比如movl这条指令,程序员调用后,将立即数0x4050送到寄存器%eax中.

        指令码的实现由芯片开发人员完成,我们可以设想一下:把一个十六进制数0x4050,送到%eax中,按照二进制0B0100 0000 0101 0000,CPU接到这条指令,把%eax(32位寄存器)中对应的值等于1的位打开,对应值等于0的位关闭.------------这段属于超纲内容,知道他的结果就行了.

        CPU有个特点:只能处理来自寄存器的数据,指令中的操作数必须经寄存器传给CPU.寄存器的作用是把内存的数据调入交给CPU处理;再将CPU处理好的数据交给内存.简而言之,寄存器是用来中转数据的.

        2>认识寄存器

        本书P120画出了x86-64的整数寄存器图,如果想使用汇编语言,这张图挺重要,最好能熟悉.

         简单认识一下寄存器,有64位,32位,16位,8位之分,分别对应四字,双字,字和字节.各自特点如下:

                 64位寄存器特点:以"r"开头,非"d"结尾

                 32位寄存器特点:以"e"开头或者"d"结尾

                 8位寄存器特点:以"l"或者"b"结尾

                  其余是16位寄存器 

         在P120倒数第二段,有关于寄存器指令的特别规则:当这些指令以寄存器为目标时,生成4字节数的指令会把高位4个字节置0.

        说明:指令有以下2个特点:

        1)指令有单个操作数或者两个操作数(3个以上的暂时还没见过)

        2)指令末尾要加上表示操作数字节长度的标识(字节加b,字加w,双字加l,四字加q)

        当第2个操作数为寄存器,且指令以"l"结尾时,高位4个字节将置0.

        3>每个寄存器的作用   

         本书P120最后一段,强调了栈指针%rsp,知名运行时栈的结束位置.P121第一段:有一组标准的编程规范控制着如何使用寄存器来管理栈、传递函数参数、从函数的返回值,以及存储局部和临时数据.(黑体字是原话).这段话表明了寄存器有使用规则,具体怎样使用在3.7节

二.操作数指示符

          操作数的类型有三种:立即数,直接寻址(寄存器寻址和内存寻址),间接寻址(内存地址).为了方便下面的理解:操作数其实是两个类型,立即数和地址

          操作数的抽象模型是这样的:

        以下是直接寻址和间接寻址的示意图 

        

        直接寻址:当标识是寄存器名称或者内存时,实际上表示的是他的数值

        间接寻址:当标识用()括起来的寄存器名称或者内存时,表示以他的数值为地址内的数值.

        由此引出一个非常重要!非常重要的概念

                 内存中的数据都是以地址形式出现(立即数除外)

        从这个结论对前面所学内容做个回顾和对比:

        1.首先是指针的重要性,在C语言等高级语言中,有"变量"的存在.变量是为了方便编写和使用程序的人理解而设置的.CPU不认识变量,他是通过数据地址来运算的.所以变量是地址的代名词

        2.立即数的用途不多,在高级语言中,一般使用枚举来表示常量,避开硬编码,侧面加强了这个概念,突出地址的重要性.

        3.地址传递数据这一机制,由接收方直接寻址或间接寻址来表达传的是值或者指针,非常好用.这句话很拗口,用代码来说明

//以下标记为代码段1
movew $0x1040,0xff00        //把0x1040写入地址0xff00
movew $0x1000,0x1040        //把0x1000写入地址0x1040 
movew 0xff00,%ax            //把0xff00的值0x1040传给寄存器%ax
movew %ax,0x40              //把寄存器%ax里的值传给地址0x40,此时0x40的值等于0x1040
movew (%ax),%rdx            //把寄存器%ax值表示的地址的值传给%rdx,此时%rdx值等于0x1000

         由%ax接收数据后,%ax表示接收到的值,由(%ax)表示值的地址里的值.因此可以忽略数据类型是"变量"还是"指针".这一点细微的差别,能感觉得出比起高级语言中需声明指针,再间接访问数据这种写法来得更好.-------第3点属于思路发散,实际意义没多少,个人感觉创造出"间接寻址"这个概念的人很厉害

        关于操作数指示符的其他内容,可以参看本书P121和P122,并做一做练习题.

三.数据传送指令

        本书P122说了数据传送指令是最频繁使用的指令.回到编程的根本目的---用数据来表示结果.传送指令相当于直接写入结果. 运行程序中各种参数传递,结果回传等,都会用到move指令,所以使用很多.

        笔者把数据传送指令的规则做个归纳和说明

        1>源操作数可以是立即数,寄存器或者内存地址;目的操作数必须是地址

                和上面操作数讲的一样,源操作数用寄存器名称或者内存地址,表示他的数值.目的操作数必须是地址,不能是立即数.以下写法错误

//错误写法
movew 0x40 $0xff00        //目的操作数是立即数

           2>源操作数和目的操作数不能都是地址,如果把一个地址的数据传到另一个地址中,需要经过寄存器,两步转换.

movew 0xff00,%ax            //把0xff00的值传给寄存器%ax
movew %ax,0x40              //把寄存器%ax里的值传给地址0x40

这样写是错的

//以下为错误写法
movew 0xff00,0x40         //不能将一个内存的值直接传给另一个内存地址
//以下是正确写法
movew $0x40 0xff00        //立即数写入内存

                3>寄存器部分的大小必须与指令最后一个字符(b,w,l,q)指定大小匹配(本书P123原话).move指令对于内存地址没有限制

moveb %ax,0xff00    //错误,b表示字节,%ax表示字,大小不匹配
moveb %al,%bl       //正确,寄存器大小匹配

                4>特殊的movl指令:movl指令用于替代movzlq指令.和寄存器特殊运算规则一样,当以寄存器为目的操作数,指令使用movl时,它会将该寄存器的高位4字节设置为0. 

movl %eax,%rdx    //错误,%rdx高4字节位被置0(不可预料后果)

                5>某些寄存器不能被作为目的操作数                

movb $0xf,(%ebx)    //错误,被调用者保留位,不能被写入

====================================内容分割线============================ 

         笔者在看完了move指令的用法,做了相关习题后,确实有些"嫌"汇编语言.他好不好学,好不好用笔者不知道,但就只是一个指令,就有这么多规则要遵守,在写代码段1的时候,还很小心地对地址进行了计算(每个数据占8个字节,因此地址末尾应该是0x00,0x40,0x80,0xc0)

        回到理解汇编语言的初衷,加深对C语言的认识,以及优化代码的基础上去学汇编语言是很好的.但如果可以用高级语言替代,又没有那么大的兴趣去研究的话,相关内容可以考虑不看.

====================================内容分割线============================ 

          P125的3.4.3数据传送示例,有一个地方需要注意,在程序传参的过程中,实际上还发生了一些代码调用.具体要结合程序中上面的代码.

//将xp地址传给寄存器%rdi(第一个参数),这里xp是形参,实际上是实参地址
//将y地址传给寄存器%rsi(第二个参数),这里y是形参,实际上是实参地址
//xp in %rdi的伪代码实现,y in %rsi的伪代码实现
moveq xp地址 %rdi    
moveq y地址 %rsi

 四.程序栈的初识

        本书P127有几句重要的内容(黑体字是原话)

        1>程序栈存放在内存某个区域

        2>栈向下增长

        3>栈指针%rsp保存着栈顶元素的地址

        这里程序栈内容并没有讲栈内内容如何与寄存器产生数据交互.

        重点:栈指针始终指向栈顶,保存着栈顶元素的地址.每当数据压入栈中,栈顶地址值加8(8个字节),每当数据弹出栈,栈顶地址值减8,汇编代码如下

subq $8,%rsp        //数据压栈,栈向下增长,栈顶元素地址减8
addq $8,%rsp        //数据出栈,栈向上增长,栈顶元素地址加8

        栈指针%rsp的作用,就和指向链表首个元素的指针一样(可以访问链表中任意一个元素),获得栈指针可以访问栈内任意元素(每次移动8个字节.),并将其传给寄存器,以使CPU获得数据后执行指令.

小结

        3.4节的内容对理解程序的执行过程还是非常重要的

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2198765.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

智能电子价签:助力零售效率升级的关键

在竞争日益激烈的零售市场&#xff0c;如何优化运营、提升效率&#xff0c;是每个零售商都在关注的问题。电子价签作为一项创新技术&#xff0c;提供了蒿效的解决方案。今天&#xff0c;我们就来聊聊电子价签如何帮助零售商轻松管理信息、减少人工误差&#xff0c;并展示它在门…

【AI绘画】Midjourney进阶:对称构图详解

博客主页&#xff1a; [小ᶻZ࿆] 本文专栏: AI绘画 | Midjourney 文章目录 &#x1f4af;前言&#x1f4af;什么是构图为什么Midjourney要使用构图 &#x1f4af;对称构图特点使用场景提示词书写技巧测试 &#x1f4af;小结 &#x1f4af;前言 通常来学习AI绘画的人可以分为…

遥感影像-语义分割数据集:多源多模态地物多要素数据集详细介绍及训练样本处理流程

原始数据集详情 简介&#xff1a;该数据集由WHU-OPT-SAR数据集整理而来&#xff0c;覆盖面积51448.56公里&#xff0c;分辨率为5米。据我们所知&#xff0c;WHU-OPT-SAR是第一个也是最大的土地利用分类数据集&#xff0c;它融合了高分辨率光学和SAR图像&#xff0c;并进行了充…

非酒精性脂肪性肝炎NASH临床赛道的百米冲刺,谁将成为胜者?

前 言 非酒精性脂肪性肝炎&#xff08;NASH&#xff09;是一种与肥胖、血脂异常、2型糖尿病和代谢综合征密切相关的疾病&#xff0c;可能会发展为肝硬化、终末期肝病甚至肝癌。据美国肝脏基金会统计数据显示&#xff0c;截至2023年8月&#xff0c;美国成年人中有5%的NASH患者…

使用 YOLOv 11 模型实现实时手语检测 可同时识别多个手语手势

项目&#xff1a;Yolo11 - Roboflow - OpenCV 手语是聋哑人之间以及他们与外界沟通的重要工具&#xff0c;然而&#xff0c;许多不会手语的人无法与他们有效交流。这个项目的目标是通过自动检测手语手势&#xff0c;构建一个可以帮助聋哑人和普通人之间沟通的桥梁&#xff0c;…

立体扬声器棒球帽专利TRO维权,速查避免踩坑

案件基本情况起诉时间&#xff1a;2024-9-18案件号&#xff1a;24-cv-08626原告&#xff1a;Audiowear Technology Corporation原告律所&#xff1a;Loza & Loza, LLP起诉地&#xff1a;伊利诺伊州北部法院品牌介绍Audiowear Technology Corporation&#xff0c;一家位于特…

麒麟V10系统下的调试工具(网络和串口调试助手)

麒麟V10系统下的调试工具&#xff08;网络和串口调试助手&#xff09; 1.安装网络调试助手mnetassist arm64-main ①在linux下新建一个文件夹 mkdir /home/${USER}/NetAssist②将mnetassist arm64-main.zip拷贝到上面文件夹中&#xff0c;并解压给权限 cd /home/${USER}/Ne…

(23)DBPSK信号在Rayleigh衰落信道条件下的传输性能仿真

文章目录 前言一、MATLAB仿真代码二、仿真结果画图 前言 此示例创建了一个【频率平坦的瑞利衰落信道】对象&#xff0c;并使用该对象来对DBPSK信号进行衰落处理&#xff0c;衰落之后增加了不同信噪比的AWGN&#xff0c;计算出不同的信噪比值计算误码率&#xff0c;并和理论误码…

八、索引的创建与设计原则

文章目录 1. 索引的声明与使用1.1 索引的分类1.2 创建索引1.2.1 在创建表时创建索引1.2.2 在已经存在的表上创建索引1.3 删除索引2. MySQL8.0索引新特性2.1 支持降序索引2.2 隐藏索引3. 索引的设计原则3.1 数据准备3.2 哪些情况适合创建索引3.2.1 字段的数值有唯一性的限制3.2.…

Cisco Catalyst 9000 交换产品系列 IOS XE 17.15.1 发布下载,新增功能概览

Cisco Catalyst 9000 Series Switches, IOS XE Release 17.15.1 ED 思科 Catalyst 9000 交换产品系列 IOS XE 系统软件 请访问原文链接&#xff1a;https://sysin.org/blog/cisco-catalyst-9000/&#xff0c;查看最新版。原创作品&#xff0c;转载请保留出处。 作者主页&…

Google:敏感信息访问权限和 API 政策更新

目录 公布时间公布内容内容有关 Google Play 照片和视频权限政策的详细信息截止时间相关问题公布时间 公布日期:2023-10-25 公布内容 内容 为向用户提供更注重隐私保护的体验,我们将推出“照片和视频访问权限”政策,以减少获准针对照片/视频请求广泛权限(READ_MEDIA_IM…

探索 ACM:计算机领域的卓越组织

《探索 ACM&#xff1a;计算机领域的卓越组织》 在计算机科学的广袤星空中&#xff0c;ACM&#xff08;Association for Computing Machinery&#xff0c;美国计算机协会&#xff09;犹如一颗璀璨的巨星&#xff0c;散发着耀眼的光芒。 ACM 是世界上最大的计算机领域专业性学…

从给定的序列中随机抽取一个元素secrets.choice()

【小白从小学Python、C、Java】 【考研初试复试毕业设计】 【Python基础AI数据分析】 从给定的序列中随机抽取一个元素 secrets.choice() [太阳]选择题 根据给定的Python代码&#xff0c;哪个选项是不可能输出的&#xff1f; import secrets sequence ["red", &qu…

PCL 法线空间下采样滤波

目录 一、概述二、代码三、结果 一、概述 对于原始点云&#xff0c;通过其点云法向量进行下采样&#xff0c;在法向量变化大的地方采样密度大&#xff0c;在法向量变化小的地方&#xff0c;采样密度小。 计算点云的空间法向量。依次计算相邻点之间的法向量夹角&#xff0c;以此…

Node.js管理工具NVM

nvm&#xff08;Node Version Manager&#xff09;是一个用于管理多个 Node.js 版本的工具。以下是 nvm 的使用方法和一些常见命令&#xff1a; 一、安装 nvm 下载 nvm&#xff1a; 地址&#xff1a;https://github.com/coreybutler/nvm-windows/releases访问 nvm 的 GitHub 仓…

Autodesk Flame 2025:视觉特效制作解决方案

Autodesk Flame 2025是一款功能强大的视觉特效制作解决方案&#xff0c;由Autodesk公司开发。它提供了出色的性能&#xff0c;为视觉特效艺术家成功完成制作项目提供了所需的交互性和灵活性。 以下是Autodesk Flame 2025的一些主要特点和功能&#xff1a; 高效的三维合成环境&…

C语言 | Leetcode C语言题解之第464题我能赢吗

题目&#xff1a; 题解&#xff1a; typedef struct HashItem {int key;bool val;UT_hash_handle hh; } HashItem;bool dfs(int maxChoosableInteger, int usedNumbers, int desiredTotal, int currentTotal, HashItem **memo) {HashItem *pEntry NULL;HASH_FIND_INT(*memo, …

C# 图像平移

图像平移&#xff1a;图像的平移是将一幅图像上的所有点都按照给定的偏移量在水平方向沿x轴、在垂直方向上沿y轴移动&#xff0c;平移后的图像与原图像大小相同。设(x0,y0) 为原图像上的一点&#xff0c;图像水平平移量为△x&#xff0c;垂直平移量为△y&#xff0c;则平移后点…

什么是词嵌入(Word Embedding)

1. 什么是词嵌入(Word Embedding) ⾃然语⾔是⼀套⽤来表达含义的复杂系统。在这套系统中&#xff0c;词是表义的基本单元。顾名思义&#xff0c;词向量是⽤来表⽰词的向量&#xff0c;也可被认为是词的特征向量或表征。把词映射为实数域向量的技术也叫词嵌⼊&#xff08;word e…

【优选算法】(第二十七篇)

目录 重排链表&#xff08;medium&#xff09; 题目解析 讲解算法原理 编写代码 合并K个升序链表&#xff08;hard&#xff09; 题目解析 讲解算法原理 编写代码 重排链表&#xff08;medium&#xff09; 题目解析 1.题目链接&#xff1a;. - 力扣&#xff08;LeetCod…