速通汇编(五)认识段地址与偏移地址,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.rhkb.cn/news/425963.html

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

相关文章

替换 Oracle ,江河信息用 TDengine 解决高基数查询写入问题

在数字经济快速发展的背景下,智慧水利作为重要的基础设施之一,正逐步成为提升水资源管理效率、优化生态环境的重要力量。江西省水投江河信息技术有限公司(以下简称“江河信息”)作为高新技术国有企业,坚定致力于打造数…

【 html+css 绚丽Loading 】 000052 璇玑转轮

前言:哈喽,大家好,今天给大家分享今天给大家分享一篇文章!并提供具体代码帮助大家深入理解,彻底掌握!创作不易,如果能帮助到大家或者给大家一些灵感和启发,欢迎收藏关注哦 &#x1f…

Golang | Leetcode Golang题解之第404题左叶子之和

题目: 题解: func isLeafNode(node *TreeNode) bool {return node.Left nil && node.Right nil }func sumOfLeftLeaves(root *TreeNode) (ans int) {if root nil {return}q : []*TreeNode{root}for len(q) > 0 {node : q[0]q q[1:]if no…

springbootadmin源码编译修改001_node版本管理工具nvm_任意切换node版本_没有成功记录过程---VUE工作笔记0026

由于项目需要对springbootadmin的源码进行编译和修改. 但是springbootadmin的源码编译很麻烦,主要是由于,springbootadmin-server-ui这个项目,因为他是一个前后端分离的 vue项目,而且是使用 https://github.com/coreybutler/nvm-windows/releases/tag/1.1.12 首先去下载,发…

无人机培训机构技术股份合作探讨

随着无人机技术的飞速发展,其在航拍、农业、物流、环境监测、应急救援等多个领域展现出巨大潜力,市场对无人机专业人才的需求急剧增加。鉴于此,多家致力于无人机培训教育的机构决定携手合作,通过技术股份合作模式,共同…

C++二叉搜索树学习

目录 一、二叉搜索树概念 二、二叉搜索树的性能分析 三、二叉搜索树的构建 一、二叉搜索树概念 二叉搜索树又叫做二叉排序树,它可以是一颗空树,或者是具有以下性质的二叉树: 若该树的左子树不为空,那么左子树上的任一节点都小…

【Google Chrome Windows 64 version及 WebDriver 版本】

最近升级到最新版本Chrome后发现页面居然显示错乱实在无语, 打算退回原来的版本, 又发现官方只提供最新的版本下载, 为了解决这个问题所有收集了Chrome历史版本的下载地址分享给大家. Google Chrome Windows version 64 位 VersionSize下载地址Date104.0.5112.10282.76 MBhtt…

【HTML】元素的分类(块元素、行内元素、行内块元素)

元素的分类 块元素行内元素行内块元素转换 块元素 独占一行&#xff0c;宽度默认为容器的100%&#xff0c;可以设置宽、高、行高、内外边距&#xff1b;布局时&#xff0c;块元素可以包含块元素和行内元素 <div>div</div><p>p</p><h3>h1-h6</…

C++——内存管理

目录 引言 C/C的内存分布 C语言中动态内存管理方式 C内存管理方式 1.new/delete操作内置类型 2.new与delete操作自定义类型 operator new与operator delete函数 new与delete的实现 1.内置类型 2.自定义类型 定位new表达式 malloc/free和new/delete的区别 结束语 引…

关于Spring Cloud Gateway中 Filters的理解

Spring Cloud Gateway中 Filters的理解 Filters Filters拦截器的作用是&#xff0c;对请求进行处理 可以进行流量染色 ⭐增加请求头 例子 spring:cloud:gateway:routes:- id: add_request_header_routeuri: http://localhost:8123predicates:- Path/api/**filters:- AddR…

Redis的缓存穿透、缓存雪崩、缓存击穿怎么解决

Redis在实际使用中是会遇到很多问题的&#xff0c;例如今天说到的缓存穿透、缓存雪崩、缓存击穿。 缓存穿透&#xff1a; 缓存穿透是指客户端请求的数据在redis缓存和数据中都不存在&#xff0c;这样缓存永远都不会生效&#xff0c;这些请求都会打到数据库当中&#xff0c;对…

MySQL_数据类型简介

课 程 推 荐我 的 个 人 主 页&#xff1a;&#x1f449;&#x1f449; 失心疯的个人主页 &#x1f448;&#x1f448;入 门 教 程 推 荐 &#xff1a;&#x1f449;&#x1f449; Python零基础入门教程合集 &#x1f448;&#x1f448;虚 拟 环 境 搭 建 &#xff1a;&#x1…

Setting Design Properties

设置设计属性 接下来&#xff0c;在设计上设置配置模式。这是导致物理 约束&#xff0c;在这种情况下是设计的属性&#xff0c;而不是单元的属性。首先&#xff0c;列出所有 当前设计的特性。 1.在Tcl控制台中列出设计的属性&#xff1a; list_property [current_design] 此命…

ITOP-2 分模块安装部署itop

ITOP-2 分模块安装部署itop 一、安装PHP组件1、查看当前Linux服务器安装的PHP版本2、安装源epel&#xff0c;安装源remi&#xff0c;安装yum-config-manager3、用yum-config-manager指定remi的php7.2仓库4、安装升级php5、验证当前PHP的版本 二、部署 MySQL 服务1、设置 Repo2、…

基于TRIZ的救援机器人轻量化设计

在救援机器人设计中&#xff0c;轻量化是一个至关重要的目标&#xff0c;它直接关系到机器人的便携性、运输效率以及在复杂环境中的作业能力。TRIZ理论为我们提供了一套系统化的工具和方法&#xff0c;用于解决设计过程中遇到的各种挑战&#xff0c;特别是在实现轻量化目标时&a…

论文阅读-Demystifying Misconceptions in Social Bots Research

论文链接&#xff1a; https://arxiv.org/pdf/2303.17251 目录 摘要: Introduction Methodological issues Information leakage Cherry-picking&#xff08;采摘樱桃&#xff09; Straw-man methodology &#xff08;稻草人&#xff09; Data biases Conceptual issu…

基于ssm+vue+uniapp的智能停车场管理系统小程序

开发语言&#xff1a;Java框架&#xff1a;ssmuniappJDK版本&#xff1a;JDK1.8服务器&#xff1a;tomcat7数据库&#xff1a;mysql 5.7&#xff08;一定要5.7版本&#xff09;数据库工具&#xff1a;Navicat11开发软件&#xff1a;eclipse/myeclipse/ideaMaven包&#xff1a;M…

vue2基础系列教程之todo的实现及面试高频问题

关键知识点 v2里面&#xff0c;当在同一个元素或组件上同时使用v-for和v-if,v-for的权限高于v-if v-show和v-if的区别主要有 v-if是惰性的&#xff0c;v-show是及时的v-if值为false时&#xff0c;不会生成dom,v-show不管值是true或false,都会生成dom,修改的是dom的display属性…

传知代码-KAN卷积:医学图像分割新前沿

代码以及视频讲解 本文所涉及所有资源均在传知代码平台可获取 概述 在本文中深入探讨KAN卷积在医学图像分割领域的创新应用&#xff0c;特别是通过引入Tokenized KAN Block&#xff08;Tok Kan&#xff09;这一突破性设计&#xff0c;将深度学习中的图像分割技术推向了新的高…

轮转数组 给定一个整数数组 nums,将数组中的元素向右轮转 k 个位置,其中 k 是非负数

示例 1: 输入: nums [1,2,3,4,5,6,7], k 3 输出: [5,6,7,1,2,3,4] 解释: 向右轮转 1 步: [7,1,2,3,4,5,6]向右轮转 2 步: [6,7,1,2,3,4,5] 向右轮转 3 步: [5,6,7,1,2,3,4]示例 2: 输入&#xff1a;nums [-1,-100,3,99], k 2 输出&#xff1a;[3,99,-1,-100] 解释: 向右…