一文说透汇编语言中的各种地址

前言

由于笔者水平有限,随笔中难免有些许纰漏和错误,希望广大读者能指正。

一、各种地址之间的区分

笔者在刚开始学习汇编语言时,不是很能分清楚汇编地址、逻辑地址、物理地址、段地址、偏移地址、线性地址等概念,这对之后学习造成了不小了影响。在花费了一番功夫之后,终于理清楚了其中的异同,希望对初学者有一些帮助。

1.逻辑地址与物理地址

在x86处理器的实模式中,逻辑地址就是段地址:偏移地址,段地址必须能被16整除,偏移地址是相对于段起始地址的偏移。下面的代码用于访问位于0x7c00:0x4e中的字节

mov al [0x7c00:0x4e]

x86处理器内置了CS、DS、SS、ES四个段寄存器,在程序执行之前,必须设置好这两个寄存器的值。处理器的总线接口部件负责把逻辑地址转换为物理地址。
当处理器访问内存时,它把指令中的内存地址看成段内的偏移地址,而不是物理地址。比如如下代码:

add al [0x3f]

指令中源操作数[0x3f]是相对于DS寄存器中段地址的偏移量,至于为什么是DS,因为如果没有指定段地址,那么默认使用DS寄存器中的值作为段地址。
处理器把段寄存器中的地址左移四位(也就是乘以16),再将其和指令中的地址相加,就得到了物理地址。以访问0x7c00:0x4e中的字节为例,处理器实际上访问的是

0x7c00 * 16 + 0x4e = 0xaa84e

这里生成了5位的十六进制物理地址,也就是20位二进制物理地址,8086CPU是有20位地址线的,所以最多可以访问2^20BYTE=1MB的内存地址。
同样在不允许段之间重叠的情况下,每个段的最大长度是64KB,因为偏移地址也是16位的,从0000H到FFFFH。

2.汇编地址

我们编写好.asm汇编程序源文件,把它交给编译器进行编译时,为了支持段地址:偏移地址这种访问模式,编译器会把源文件整体上作为一个独立的段来处理,从零开始计算和跟踪每条指令的地址,称为汇编地址
我们可以通过让编译器生成.lst文件来查看每条指令的汇编地址。接下来以nasm编译器为例进行说明。(图中代码来自李忠老师)

汇编地址展示

如上图所示,红色部分即为每条指令的汇编地址,我们可以看到汇编地址是从0开始计算的,蓝色部分为对应指令的机器码,最右侧为汇编源代码。此外,从图中我们看出注释是不占用汇编地址的。
当程序装入物理内存之后,汇编地址是在内存段中的偏移地址。当程序加载到物理内存之后,指令在段内的偏移地址和它在汇编阶段的汇编地址是相同的。
细心的读者可能会想到,如果一个程序的大小超过了64KB了,我们就不能仅仅只是使用一个段来存储程序了。为了解决这个问题,我们可以使用以下方法:

  • 拆分程序
  • 手动切换段
  • jmp、call

拆分程序

我们可以把程序拆分为数据段、代码段、栈段,每个段使用不同的寄存器进行访问

手动切换段

我们可以修改段寄存器的值,来访问其它段。

jmp、call

对于需要频繁切换段的程序,我们使用jmp、call实现段之间的跳转。

3.线性地址

要了解线性地址,就需要先了解IA-32处理器的架构以及分页机制。这部分内容需要深入到保护模式内部。笔者在这里先挖个坑,以后补上线性地址这部分内容。初学者暂时不需要了解这部分的内容。
在这里简单地说一下线性地址。IA-32处理器支持多任务,在以上所说地分段模型下,由于每个任务地内存段是大小不一的,在任务结束运行后需要对它的内存段进行释放,这就导致了内存碎片化的问题。也就是说,可用的地址空间被分成了许多部分。
如果在这时需要运行一个新的任务,很有可能出现空闲的内存地址足够运行新任务,但是由于空闲的地址被碎片化了,导致没有一个合适的内存区域用来运行这个新任务。
为了解决这个问题,IA-32处理器支持分页功能,分页功能将物理内存空间划分成逻辑上的页。页的大小一般为4KB,通过使用页,可以简化内存管理。
当页功能未开启时,线性地址就是物理地址,这个地址由处理器的段部件生成。当页功能开启时,段部件产生的地址就不再是物理地址了,而是线性地址(Linear Address),线性地址还要经页部件转换后,才是物理地址。
启用页机制后,IA-32中的每个任务都有一个大小为4GB的虚拟地址空间,这个虚拟空间的地址,就是线性地址,经过转换,它变成了物理地址。

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

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

相关文章

什么是自动化测试?为什么要做自动化测试?如何学习自动化测试?

自动化测试是指使用软件工具和脚本来执行测试任务的过程。它可以自动化执行测试用例、生成测试报告和进行结果分析。自动化测试可以减少人工测试的工作量,并提高测试的效率和准确性。它在软件开发过程中起到了重要的作用,可以帮助开发团队快速发现和修复软件中的缺陷,确保软…

o3 发布了,摔碎了码农的饭碗

大家好,我是汤师爷~ 在 2024 年底,OpenAI 发布了最新推理模型 o3。o3模型相当炸裂,在世界级编程比赛中拿下第 175 名,打败 99.9% 的参赛者。AI 写代码都赶上顶级程序员了,程序员是不是要失业?最近不少读者反馈,像 GitHub Copilot、Claude Sonnet 3.5、Cursor 等 AI 辅助…

Diary - 2025.01.06

回到正轨了,感觉今天好像不太摆了,但还是在小摸阿发现昨天日期写成 2024 了。明天计划来说应该是主要写题解了!!! 上午还有个模拟赛,但是说不定又是像之前那样拉个 USACO 来(?)。 仍记那时 USACO 金组没 ak,t3 被卡常了,6。 明天要写的题解:Luogu P11513 [ROIR 201…

前端必备基础系列(七)原型/原型链/this

对象的原型: JavaScript中每个对象都有一个特殊的内置属性[[prototype]],这个特殊属性指向另外一个对象。 当我们访问一个对象上的某个属性时,首先会检查这个对象自身有没有这个属性,如果没有就会去[[prototype]]指向的对象查找。 那么这个特性就可以帮助我们实现继承了。 …

cv2.imwrite保存的图像是全黑的

1.保存,全黑的图像cv2.imwrite(img/test.jpg, imutils.resize(enhancedImg, height=151,width=240))2.原因分析 3.原本image是0-255的数值,现在标准化了,全都是0-1之间的数值,还原,乘以255,图片输出正常。cv2.imwrite(img/test1.jpg, imutils.resize(enhancedImg, height…

SaltStack快速入门

Saltstack快速入门 saltstack介绍 Salt,一种全新的基础设施管理方式,部署轻松,在几分钟内可运行起来,扩展性好,很容易管理上万台服务器,速度够快,服务器之间秒级通讯 主要功能:远程执行 配置管理,参考官方文档: http://docs.saltstack.cn/ 安装说明: https://docs.s…

计数问题选讲做题记录

从 $1+1$ 到 $\exp(\sum\limits_{i=1}^k\ln(1+ix))$。计数杂题。calc 考虑先不管数字之间的顺序,最后给答案乘上一个 \(n!\)。 记 \(dp_{i,j}\) 表示前 \(i\) 个数在 \([1,j]\) 之间选,所产生的总贡献,显然有 \(dp_{i,j}=dp_{i,j-1}+j\times dp_{i-1,j-1}\),最后的答案是 \…

如何构建高效的智能体

简单才是王道:构建高效 AI 智能体的秘诀!工作流为简单任务提供可预测性,而智能体在复杂场景中展现灵活性。本指南深入解析如何优化工具设计、选择框架,并平衡复杂性与性能,助你构建可靠且高效的 AI 系统。 如何构建高效的智能体Anthropic 刚刚发布了一份关于“如何构建高…

昆明理工大学计算机891考研复试真题

--昆工昆明理工大学计算机技术人工智能软件工程网络空间安全计算机系统结构计算机软件与理论计算机应用技术网络与信息安全408考研综合程序设计891计算机专业核心综合数据库系统原理

Window迷你网页服务器MyWebServer v3.8.195支持php

前言全局说明Window迷你网页服务器MyWebServer v3.8.195支持php一、说明 1.1 老版本说明、历史版本下载、php下载: https://www.cnblogs.com/wutou/p/18655971二、MyWebServer v3.8.195支持php 2.12.2免责声明:本号所涉及内容仅供安全研究与教学使用,如出现其他风险,后果自负…