速通汇编(五)认识段地址与偏移地址,CS、IP寄存器和jmp指令,DS寄存器

一,地址的概念

通常所说的地址指的是某内存单元在整个机器内存中的物理地址,把整个机器内存比作一个酒店,内存单元就是这个酒店的各个房间,给这些房间编的门牌号,类比回来就是内存单元的物理地址

在第一篇介绍debug的命令时使用过很多命令,不知你还记得与否,可点击快速复习->速通汇编(一)汇编环境配置(附资源),debug六种命令使用,四个通用寄存器_d指令怎么看寄存器中内容-CSDN博客

接下来我用e命令和d命令进行两步操作:在[0000:0000]地址处写入一串数据"123456789abc",然后再用d命令读取以验证是否成功写入

可以看到确实成功写入

0e1bedaf499144959227c06dac186f58.png

(一)物理地址的表示方式

(1)段地址:偏移地址

看上图,我刚刚在[0000:0000]地址处写入了一串数据,这个[0000:0000]就是一个确切的物理地址,它由两部分组成,冒号左边是段地址,右边是偏移地址

需要提前说明,地址一定是用16进制数来表示的!

形象来说,酒店分5层,那么其中有几个房间的门牌号是207、310、404等等,我们正常的认知都知道这里的2、3、4是根据楼层来编的,后面的07、10、04则是基于它们各自的楼层的额外编号,所以段地址和偏移地址就是一个这样类似的概念,段地址相当于楼层号,再拼上一个偏移地址就能具体到一个房间门牌号(确定了内存单元的物理地址)

(2)单个十六进制数表示地址

物理地址 = 段地址*16+偏移地址

使用这个公式,可以将一个地址确切地表示成一个数而不是用段地址:偏移地址的形式来表示(这样才方便使用地址)

举几个例子(地址是十六进制数,乘16相当于整体左移一位,再加上偏移地址即是物理地址):

①0000:0000 == 0000*16+0000 == 00000

②1100:00bc == 1100*16+00bc == 110bc

③2000:1F60 == 2000*16+1F60 == 21F60

④2100:0F60 == 2100*16+0F60 == 21F60

⑤21F6:0000 == 21F6*16+0000 == 21F60

通过上述例子,相信你很清楚了如何表示地址,并且通过后3个例子,不难领悟到,同一个物理地址,可以用多个段地址:偏移地址的形式来表示

可以用下面这个例子来证明这点,可以发现,查看[2000:1F60]处的数据和[21F6:0000]处的数据是一模一样的,它们表示的确实是同一块内存的物理地址

458f90a3272140379621b71bf339bb27.png


二 ,CS、IP寄存器和jmp指令的作用

在第一篇时我们粗略介绍过所有寄存器,现在领略了地址的概念,再趁势学习一下CS和IP寄存器的具体作用

在debug模式下,使用a命令可以在[CS:IP]地址下写入汇编指令,任意时刻,CPU都将[CS:IP]指向的内容(“指向”就是地址的形象说法)当作指令执行(当然不是说你写进去就直接执行了,你需要用命令去让它执行,比如t命令)

因此,我们可以合理规划一台机器的内存,将需要的汇编代码写在内存的某些位置,然后通过改变[CS:IP]的内容,达到运行代码的目的

那要如何修改CS和IP的内容呢?mov cs,xxxx这样吗?不可以这样,CS和IP这两个寄存器的值不能用mov指令来改变,而要用jmp指令来赋值

使用形如【jmp 段地址:偏移地址】的指令,才可以修改[CS:IP]的内容

(补充:还可以使用形如【jmp 偏移地址】的指令,这样的指令被执行之后将只改变IP寄存器的值,CS寄存器的值不变,即只改偏移地址不改变段地址)

实例:

b106e1877b7b4bb48e00126e14cd2135.png

然后在[CS:IP]正指向的地址处写下这条jmp指令,让CS和IP能够跳转到刚刚写好3条汇编的地址处

c71f7b08fe0d4c26bdc5d9536de06d4c.png

t执行[CS:IP]处的汇编【jmp 2000:1F60】,观察到CS和IP的内容确实变成了[2000:1F60]

95041c94464b4f598d747399d0edb21a.png

继续使用t命令,因为此时[CS:IP]已经指向[2000:1F60]了,那么刚刚提前写好的3条汇编理所应当地被正确执行

6eae9f023b3049d4b55dde80653b448e.png


三,DS寄存器的作用

回到开头,我们在[0000:0000]地址处写下了"123456789abc"这串数据

0e1bedaf499144959227c06dac186f58.png

现在的问题是,就好比你学习高级编程语言时,定义变量并赋值存好数据之后,要如何去使用它呢? 

使用[偏移地址]的形式,就可以取用了

这时你应该心生疑问,前面不是说要段地址:偏移地址的形式才能确定一块物理地址吗,怎么这里中括号里面只用写偏移地址了呢?这时你看这块的小标题,应该恍然大悟了吧——是的,此时段地址就由DS来决定

可以如此说:汇编中出现的形如[偏移地址]形式的地址,指的都是[DS:偏移地址],即DS*16+偏移地址处的内存

那要如何修改DS的值呢?

不能直接【mov ds,段地址】,你可以先把段地址存入ax/bx/cx/dx这四个寄存器,然后再【mov ds,寄存器

或者更加省事一点的方法,用r命令直接修改ds的值(当然在实际编程中没办法用r命令,只有debug模式下可以)

也就是说,如果我想要读取[0000:0000]处的数据,那么就先让DS寄存器来存放这里的段地址0000,然后直接写汇编【mov ax,[0]】,cpu就知道你要做的事情是将[0000:0000]处的内容赋值给ax,下面进行实例验证

①先在[cs:ip]处写好3条简单的mov指令汇编

② 修改ds寄存器的值为0000,待会段地址就是0000了

f040709ce499403e89afc049f69f7712.png

③t命令执行完提前写好的3条mov汇编,观察到ax、bx、cx寄存器的值被分别赋值成3412、5634、7856

4aafec44f46b4c6785a2e616f4f4f00c.png

我们来分析一下原因:

首先ds寄存器的值被提前修改成了0000,意味着段地址全程是0000,下图是提前在[0000:0000]处写好的数据"123456789abc"

1723f8cc2b644751bc9a637d629908cd.png

①第一条汇编是【mov ax,[0]】 ,将[0000:0000]处的内容赋值给ax,因为ax是十六位寄存器,因此它会从[0000:0000]处取4位十六进制数,12显然是不够的(才两位),因此再取后两位34凑成3412赋值给ax。

为什么是3412而不是1234呢?因为12是低地址处(偏左边)的数据,应该放在ax寄存器的低位al处;34是高地址处(偏右边)的数据,应该放在ax寄存器的高位ah处,而ax是ah+al,ah在前,也就成了3412这样看起来倒过来的数据了(自行了解一下小端存储)

②第二条汇编是【mov bx,[1]】 ,将[0000:0001]处的内容赋值给bx,因为bx是十六位寄存器,因此它会从[0000:0001]处取4位十六进制数,34显然是不够的(才两位),因此再取后两位56凑成5634赋值给ax。

③第三条汇编同理,不再赘述。

④此时我们举一反三,同样的内存数据,如果我们执行汇编【mov dh,[0]】,结果会怎样?

因为dh是八位寄存器(dx的高位),因此它只取[0000:0000]处的两位数据12就够了,然后赋值给dh

实例验证:

b787c04c437d4f0096760efa2ab6cb2d.png

⑤再举一反三, 同样的内存数据,如果执行汇编【add ax,[0]】,是不是可以把[0000:0000]处的数据和ax中的数据相加?

确实如此,如果执行【add al,[0]】也是同理的,相信你对地址已经很透彻了吧o(* ̄▽ ̄*)ブ

69101eb5a4324be4935e6ac857ad1846.png

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

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

相关文章

文心智能体应用:美国旅游助手的诞生

创造灵感 在如今的数字化时代,旅行体验越来越依赖于智能技术的辅助。从机票预订到行程安排,再到当地美食推荐,智能助手在旅行中的作用愈发重要。尤其在美国这样一个广袤且多样化的国家,拥有一个智能旅行助手能够极大地提升游客的…

C++3D迷宫

目录 开头程序程序的流程图程序游玩的效果下一篇博客要说的东西 开头 大家好&#xff0c;我叫这是我58。 程序 #include <iostream> using namespace std; void printmaze(char strmaze[5][5][5]) {cout << "-----" << endl;int i 0;int ia 0…

react18基础教程系列--安装环境及packagejson文件分析

一个React项目中&#xff0c;默认会安装: react:React框架的核心react-dom:React 视图渲染的核心「基于React构建WebApp(HTML页面)J—>react-native:构建和渲染App的react-scripts: 脚手架为了让项目目录看起来干净一些&#xff0c;把webpack打包的规则及相关的插件/LOADER…

《OpenCV计算机视觉》—— 图像金字塔

文章目录 什么是图像金字塔&#xff1f;一、定义与基本原理二、主要类型三、构建过程四、应用领域 图像金字塔中的下采样和上采样一、下采样&#xff08;Downsampling&#xff09;二、上采样&#xff08;Upsampling&#xff09;三、总结 代码实现 什么是图像金字塔&#xff1f;…

YOLOv8目标检测模型——遥感小目标检测经验分享

小目标检测——YOLOV8 一、引言 背景介绍 &#xff08;1&#xff09;目标检测的重要性 目标检测在许多领域都具有极其重要的作用。在自动驾驶中&#xff0c;目标检测能够识别道路上的障碍物和行人&#xff0c;确保行车安全。在视频监控中&#xff0c;目标检测能够实时发现异…

从登录到免登录:JSP与Servlet结合Cookie的基本实现

前言 JSP中应用Cookie解析&#xff1a; 用户登录成功后&#xff0c;将用户信息保存到Cookie中&#xff0c;在页面读取Cookie并显示&#xff0c;不需要再次登录可以直接进入页面 第一步&#xff1a;创建JavaWeb项目&#xff0c;配置pom.xml文件 创建maven项目&#xff0c;项目名…

DB-GPT部署和试用

前言 DB-GPT是一个开源的AI原生数据应用开发框架(AI Native Data App Development framework with AWEL(Agentic Workflow Expression Language) and Agents)。 目的是构建大模型领域的基础设施&#xff0c;通过开发多模型管理(SMMF)、Text2SQL效果优化、RAG框架以及优化、Mu…

Element UI入门笔记(个人向)

Element UI入门笔记 将页面分割为一级菜单、二级菜单、导航栏三个部分&#xff1b;使用npm下载安装&#xff0c;使用语句npm i element-ui -s; 布局组件 el-form 用于创建和管理表单&#xff1b;从属性上看&#xff1a; :model&#xff1a;用于双向数据绑定&#xff0c;将表单…

打造古风炫酷个人网页:用HTML和CSS3传递笔墨韵味

需要用到的背景大家可以自己找喜欢的风格!!! 当然俺把俺用的背景放到文章最后了哦&#xff01;&#xff01;&#xff01;&#xff01;&#xff01; 感谢关注和支持 长期更新哦~~~ 1. 简洁的页面布局&#xff1a;保持优雅和对称 在古风设计中&#xff0c;布局的对称性非常重要…

Linux - 探秘/proc/sys/net/ipv4/ip_local_port_range

文章目录 Pre概述默认值及其意义评估需求如何调整临时修改永久修改测试和验证 修改的潜在影响 Pre Linux - 探秘 Linux 的 /proc/sys/vm 常见核心配置 计划&#xff1a; 简要解释 /proc/sys/net/ipv4/ip_local_port_range 文件的功能和作用。介绍该文件的默认值及其影响。说明…

螺丝、螺母、垫片等紧固件常用类型详细介绍

螺钉、螺母、垫片等紧固件介绍 螺钉 杯头内六角 首先介绍一下杯头内六角&#xff0c;杯头内六角是我们用的最常见的一种螺钉&#xff0c;如果你对选择螺钉没有什么想法&#xff0c;可以直接无脑选杯头内六角去使用。 比如说我们有一个零件加工了通孔&#xff0c;另一个零件加…

Vue3.0组合式API:setup()函数

1、什么是组合式API Vue 3.0 中新增了组合式 API 的功能&#xff0c;它是一组附加的、基于函数的 API&#xff0c;可以更加灵活地组织组件代码。通过组合式 API 可以使用函数而不是声明选项的方式来编写 Vue 组件。因此&#xff0c;使用组合式 API 可以将组件代码编写为多个函…

CPU 和 GPU:为什么GPU更适合深度学习?

目录 什么是 CPU &#xff1f; 什么是 GPU &#xff1f; GPU vs CPU 差异性对比分析 GPU 是如何工作的 &#xff1f; GPU 与 CPU 是如何协同工作的 &#xff1f; GPU vs CPU 类型解析 GPU 应用于深度学习 什么是 CPU &#xff1f; CPU&#xff08;中央处理器&#xff09;…

git push : RPC failed; HTTP 400 curl 22 The requested URL returned error: 400

git push 出现RPC failed; HTTP 400 curl 22 The requested URL returned error: 400 问题 git push Enumerating objects: 11, done. Counting objects: 100% (11/11), done. Delta compression using up to 8 threads Compressing objects: 100% (10/10), done. error: RPC …

对中文进行文本分类的常用方法

一&#xff1a;关键词分类和基于规则的分类 关键词分类和基于规则的分类是两种常见的文本分类方法&#xff0c;它们可以应用于中文文本的分类。下面我将详细介绍这两种方法&#xff1a; 关键词分类 原理&#xff1a;这种方法通过识别文本中出现的特定关键词或短语来确定文本的…

STM32常用数据采集滤波算法

例如&#xff0c;STM32进行滤波处理时&#xff0c;主要目的是处理数据采集过程中可能产生的噪声和尖刺信号。这些噪声可能来自电源干扰、传感器自身的不稳定性或其他外部因素。 1.一阶互补滤波 方法&#xff1a;取a0~1,本次滤波结果&#xff08;1-a&#xff09;本次采样值a上…

基于 jenkins 的持续集成、持续部署方案

工具介绍 python3.12 fastapi 0.92.0 uvicorn 开发部署web项目&#xff1b;git gitee 实现代码版本管理&#xff1b;jenkins docker 实现持续集成、持续部署&#xff1b;centos7 作为jenkins服务器 & 部署服务器&#xff1b;有条件的可以再启动一台服务器作为部署测试…

学习笔记(一)

前言 一、对象 1、由类建模而成&#xff0c;是消息、数据和行为的组合 2、可以接收和发送消息&#xff0c;并利用消息进行彼此的交互。消息要包含传送给对象接收的信息 3、类的实例化&#xff1a;把类转换为对象的过程叫类的实例化。 4、对象的特性 (1) 对象有状态&#…

RabbitMQ Spring客户端使用

注解声明式队列和交换机 java自带序列化工具类&#xff0c;将java对象序列化为字节数组&#xff0c;用于网络传输。 jdk序列号存在缺陷&#xff0c;&#xff08;不安全&#xff0c;占用空间大等&#xff09; 推荐使用JSON的序列化&#xff1a; springboot扫描包使配置生效&…

windows下自启springboot项目(jar+nginx)

1、将springboot项目打包为jar 2、新建文本文档 test.txt&#xff0c;并输入 java -jar D:\test\test.jar&#xff08;修改为自己的jar包位置&#xff09; 保存 然后修将后缀名改为 .bat 3、在同一目录再新建 文本文档test.txt&#xff0c;输入以下内容&#xff0c;&…