为什么在.COM程序中,对于程序代码和堆栈,只有一个段?

如何解决为什么在.COM程序中,对于程序代码和堆栈,只有一个段?

我正在研究.EXE程序和.COM程序之间的区别。 .EXE对我而言是合乎逻辑的,即相对于程序代码而言,堆栈位于另一段中(实际上是强制堆栈并使用.STACK指示此限制),因此,当我在其中插入值时堆栈(在.EXE文件中),使用的段与程序不同,因此我不会混淆这两个段。

示例:

SP = 0400
SS = 3996 CS = 3995 IP = 0000

堆栈的容量为1024字节(400h),并引用堆栈段3996h,这与代码段3995h不同。因此,我确定数据不会混淆。

我不了解的事情是当我不得不处理.COM程序时;因为我很清楚他们只使用了一个细分,而我发现自己的处境与此类似:

SP = FFEE
SS = 114A CS = 114A IP = 0100

我有与代码段匹配的堆栈段。因此,如果我继续将值放在堆栈上,它们早晚会出现在我的代码中吗?

解决方法

虽然在加载COM文件后MS-DOS确实将所有段寄存器设置为程序入口上的同一段,但是没有什么阻止您更改寄存器以使用不同的段。但是,您所设想的段之间的硬分隔实际上并不存在。即使有一个单独的堆栈段,如果堆栈溢出,您仍将在不应该写入的地方写入内存,结果将不可预测。

使用第二个CS:IP为114A:0100,而SS:SP为114A:FFFE的示例,您的COM程序可以将SS:SP更改为210A:03FE。两个SS:SP值都将指向相同的线性地址(2149E)和MS-DOS在条目上推入堆栈的相同的返回值。现在,堆栈只有1024个字节,就像在EXE示例中一样,但是堆栈段仍然是64k。在实模式下,段始终为64k。

现在猜测当SS:SP为210A:0000并尝试将一个单词压入堆栈时会发生什么? CPU不会生成异常,它不会以某种方式拒绝执行该操作,它只会执行其始终执行的操作。它从SP中减去2,然后将单词存储在新的SS:SP地址中。在这种情况下,这意味着SP将绕回FFFE,并且您推入的值将存储在210A:FFFE或3109E的线性地址中。

现在的问题是,线性地址3109E分配了什么? MS-DOS可能会将此内存分配给您的程序,并在其中写入值是无害的,因为您的程序没有将其用于任何事情。但是,某些TSR或驱动程序可能会在那里分配内存并覆盖它,这将导致崩溃或其他无法预测的行为。

如果在堆栈溢出时重写自己的代码,实际上会更好,因为这意味着您更有可能注意到该错误并进行修复。

EXE也存在相同的环绕问题。如果您想要一个真正隔离的堆栈,则需要制作64K的大小,但是在溢出时发生的事情是该堆栈会覆盖自身,因此从根本上不能解决问题。最终,作为开发人员,您有责任确保程序为自己分配了足够的堆栈空间,并且您的代码永远不会超过该限制。


请注意,COM文件需要担心一个与堆栈相关的陷阱,并且不能保证MS-DOS能够为您的COM文件分配完整的64K。 MS-DOS将分配COM文件将适合的最大的空闲内存块。如果该内存块小于64K,则SP不会设置为FFFE,而是将SP设置为指向分配给程序的最后一个字。在最坏的情况下,这意味着堆栈将立即开始覆盖您的COM文件中的代码和数据。因此,最好在COM文件末尾分配空间以为堆栈保留空间。

,

*。com文件可以将功能为4ah的ram大小调整为可执行文件的最小值,并最终从功能为48h的DOS中获取免费的ram。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


依赖报错 idea导入项目后依赖报错,解决方案:https://blog.csdn.net/weixin_42420249/article/details/81191861 依赖版本报错:更换其他版本 无法下载依赖可参考:https://blog.csdn.net/weixin_42628809/a
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下 2021-12-03 13:33:33.927 ERROR 7228 [ main] o.s.b.d.LoggingFailureAnalysisReporter : *************************** APPL
错误1:gradle项目控制台输出为乱码 # 解决方案:https://blog.csdn.net/weixin_43501566/article/details/112482302 # 在gradle-wrapper.properties 添加以下内容 org.gradle.jvmargs=-Df
错误还原:在查询的过程中,传入的workType为0时,该条件不起作用 <select id="xxx"> SELECT di.id, di.name, di.work_type, di.updated... <where> <if test=&qu
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct redisServer’没有名为‘server_cpulist’的成员 redisSetCpuAffinity(server.server_cpulist); ^ server.c: 在函数‘hasActiveC
解决方案1 1、改项目中.idea/workspace.xml配置文件,增加dynamic.classpath参数 2、搜索PropertiesComponent,添加如下 <property name="dynamic.classpath" value="tru
删除根组件app.vue中的默认代码后报错:Module Error (from ./node_modules/eslint-loader/index.js): 解决方案:关闭ESlint代码检测,在项目根目录创建vue.config.js,在文件中添加 module.exports = { lin
查看spark默认的python版本 [root@master day27]# pyspark /home/software/spark-2.3.4-bin-hadoop2.7/conf/spark-env.sh: line 2: /usr/local/hadoop/bin/hadoop: No s
使用本地python环境可以成功执行 import pandas as pd import matplotlib.pyplot as plt # 设置字体 plt.rcParams['font.sans-serif'] = ['SimHei'] # 能正确显示负号 p
错误1:Request method ‘DELETE‘ not supported 错误还原:controller层有一个接口,访问该接口时报错:Request method ‘DELETE‘ not supported 错误原因:没有接收到前端传入的参数,修改为如下 参考 错误2:cannot r
错误1:启动docker镜像时报错:Error response from daemon: driver failed programming external connectivity on endpoint quirky_allen 解决方法:重启docker -> systemctl r
错误1:private field ‘xxx‘ is never assigned 按Altʾnter快捷键,选择第2项 参考:https://blog.csdn.net/shi_hong_fei_hei/article/details/88814070 错误2:启动时报错,不能找到主启动类 #
报错如下,通过源不能下载,最后警告pip需升级版本 Requirement already satisfied: pip in c:\users\ychen\appdata\local\programs\python\python310\lib\site-packages (22.0.4) Coll
错误1:maven打包报错 错误还原:使用maven打包项目时报错如下 [ERROR] Failed to execute goal org.apache.maven.plugins:maven-resources-plugin:3.2.0:resources (default-resources)
错误1:服务调用时报错 服务消费者模块assess通过openFeign调用服务提供者模块hires 如下为服务提供者模块hires的控制层接口 @RestController @RequestMapping("/hires") public class FeignControl
错误1:运行项目后报如下错误 解决方案 报错2:Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.8.1:compile (default-compile) on project sb 解决方案:在pom.
参考 错误原因 过滤器或拦截器在生效时,redisTemplate还没有注入 解决方案:在注入容器时就生效 @Component //项目运行时就注入Spring容器 public class RedisBean { @Resource private RedisTemplate<String
使用vite构建项目报错 C:\Users\ychen\work>npm init @vitejs/app @vitejs/create-app is deprecated, use npm init vite instead C:\Users\ychen\AppData\Local\npm-