在 REP MOVSW 之前 PUSH CS / POP DS 的目的是什么?

2024-05-01

为什么在下面的代码中我们压入代码段(PUSH CS)然后将其弹出到数据段(POP DS)?

我将这些行明确指定为 line1 和 line2。请告诉我 MOVSW 在这里是如何工作的。

IF  HIGHMEMORY
PUSH DS
MOV BX, DS
ADD BX, 10H
MOV ES, BX
PUSH CS.           ;line1
POP DS.            ;line2
XOR SI, SI
MOV DI, SI
MOV CX, OFFSET SYSSIZE  +  1
SHR CX, 1
REP MOVSW.    ;line3
POP DS
PUSH ES
MOV AX, OFFSET SECONDRELOCATION
PUSH AX
AAA PROC FAR
RET
AAA ENDP 
SECONDRELOCATION:
more code here.............. 

暂时设置 DS = CS 然后恢复它看起来是使用 CS 覆盖前缀的低效替代方案rep movsw.

段覆盖可以更改源movsw http://felixcloutier.com/x86/MOVS:MOVSB:MOVSW:MOVSD:MOVSQ.html from DS:SI to CS:SI。 (目的地为ES:DI不能被覆盖)。

(更新:在原始 8086/8088 上,存在一个硬件“错误”/异常:从 REP 字符串指令期间发生的中断恢复时,IP 将指向last指令的前缀,而不是第一个。所以根据编码,cs rep movsw会解码为rep movsw or cs movsw。请参阅@MichaelPetch 的评论,以及https://www.pcjs.org/pubs/pc/reference/intel/8086/ https://www.pcjs.org/pubs/pc/reference/intel/8086/有关更多 8086 勘误表和已在更高版本的 x86 CPU 中修复的异常情况。)


这段代码正在做一个memcpy(dst, code_segment, sizeof(code_segment)),其中dst段:偏移量是(BX + 16):0。之前的说明rep movsw设置 DS = BX+16,设置 DI=0。

然后代码跳转到新位置,使用farret在推送目标段(ES)和其中的偏移量之后。 (push offset SECONDRELOCATION可以,但仅限于 186+。不幸的是,这个 DOS 代码需要保持与 8086 的向后兼容。)

显然这个汇编器不支持这样的语法ret far or retf,所以他们必须组装一个远ret通过声明一个指令proc far周围的ret操作说明。AAA这个过程的名字很奇怪,因为aaa也是有效的 x86 指令助记符(添加后的 ASCII 调整) http://felixcloutier.com/x86/AAA.html.

所以执行继续在SECONDRELOCATION:在我们刚刚制作的代码副本中添加标签。


(size+1) / 2向上舍入为整数个字,除非大小回绕,在这种情况下它会复制零字节而不是 64k。 (不像loop, rep检查计数before执行一次。)

正在做的shr在运行时也是愚蠢的,可以在汇编时使用类似的东西来完成mov cx, (offset endcode - startcode + 1) / 2。 (你可能无法将offset结果除以 2,但您可以在组装时找到同一部分中两个标签之间的距离。)

不管怎样,重点可能是将代码重新定位到 HIGHMEM 中,留下低内存以供不能使用 HIMEM 的程序使用。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在 REP MOVSW 之前 PUSH CS / POP DS 的目的是什么? 的相关文章

  • C++ 中的 CPUID 实现

    我想知道这里是否有人有一些可以从任何托管 net 语言引用的 C CPUID 实现的好示例 另外 如果情况并非如此 我是否应该注意 X86 和 X64 之间的某些实现差异 我想使用 CPUID 来获取运行我的软件的机器上的信息 崩溃报告等
  • 即使我确实为变量设置了初始值,数据段也没有被初始化

    我已经编写了一个代码 该代码应该生成某种数字列表 但是即使我为它们分配了初始值 我的数据段变量也没有被初始化 This is how DS 0000 looks when I run it 这是我的代码 但数据段只保留垃圾值 MODEL s
  • 在 x86 程序集中将整数打印到控制台

    当我在 16 位汇编中添加两个值时 将结果打印到控制台的最佳方法是什么 目前我有这个代码 CODE START mov ax 1 put 1 into ax add ax 2 add 2 to ax current value mov ah
  • NASM 轮班操作员

    您将如何在寄存器上进行 NASM 中的位移位 我读了手册 它似乎只提到了这些操作员 gt gt lt lt 当我尝试使用它们时 NASM 抱怨移位运算符处理标量值 您能解释什么是标量值并举例说明如何使用 gt gt and lt lt 另外
  • 为什么 Visual Studio 使用 xchg ax,ax

    我正在查看程序的反汇编 因为它崩溃了 并注意到很多 xchg ax ax 我用谷歌搜索了一下 发现它本质上是一个 nop 但是为什么 Visual Studio 会执行 xchg 而不是 noop 该应用程序是一个C NET3 5 64位应
  • 在 x86-64 CPU 上通过交叉修改代码重现意外行为

    Question 对于可能在 x86 或 x86 x64 系统上触发意外行为的交叉修改代码有哪些想法 在这些系统中 交叉修改代码中的所有操作均已正确完成 但在执行处理器之前执行序列化指令除外修改代码 如下所述 我有一个 Core 2 Duo
  • 两个基本的 ANTLR 问题

    我正在尝试使用 ANTLR 来获取简单的语法并生成汇编输出 我在 ANTLR 中选择的语言是 Python 许多教程看起来非常复杂或详细阐述与我无关的事情 我真的只需要一些非常简单的功能 所以我有两个问题 将值从一个规则 返回 到另一规则
  • 在 x86 ASM 中测试零通常哪个更快:“TEST EAX, EAX”与“TEST AL, AL”?

    测试 AL 中的字节是否为零 非零通常哪个更快 TEST EAX EAX TEST AL AL 假设之前有一个 MOVZX EAX BYTE PTR ESP 4 指令加载了一个带有零扩展的字节参数到 EAX 的其余部分 防止了我已经知道的组
  • 使用 Easy 68K (68000) 组装范围内的随机数

    我正在使用 Easy 68K 模拟器创建一个简单的黑杰克游戏 需要使用随机数来分配牌 我的牌必须在 2 到 11 的范围内 我似乎每次都得到相同的数字 但它不在我预期的范围内 我的卡值需要以 D3 结束 因此我有以下随机数代码 CLR L
  • 如何知道寄存器是否是“通用寄存器”?

    我试图了解寄存器必须具备什么标准才能被称为 通用寄存器 我相信通用寄存器是一个可以用于任何用途的寄存器 用于计算 将数据移入 移出等 并且是一个没有特殊用途的寄存器 现在我读到了ESP寄存器是通用寄存器 我猜是ESP寄存器可以用于任何事情
  • 为什么我的空循环在 Intel Skylake CPU 上作为函数调用时运行速度是原来的两倍?

    我正在运行一些测试来比较 C 和 Java 并遇到了一些有趣的事情 在 main 调用的函数中 而不是在 main 本身中 运行具有优化级别 1 O1 的完全相同的基准代码 导致性能大约翻倍 我正在打印 test t 的大小 以毫无疑问地验
  • 如何在 Linux x86_64 上模拟 iret

    我正在编写一个基于 Intel VT 的调试器 由于当 NMI Exiting 1 时 iret 指令在 vmx guest 中的性能发生了变化 所以我应该自己处理vmx主机中的NMI 否则 guest会出现nmi可重入错误 我查了英特尔手
  • 如何使用movntdqa避免缓存污染?

    我正在尝试编写一个 memcpy 函数 该函数不会将源内存加载到 CPU 缓存中 目的是避免缓存污染 下面的 memcpy 函数可以工作 但会像标准 memcpy 一样污染缓存 我正在使用带有 Visual C 2008 Express 的
  • AVX-512 指令编码 - {er} 含义

    在 Intel x86 指令集参考中 有许多 AVX 512 指令在指令中具有可选的 er 例如 VADDPD 的一种形式定义为 EVEX NDS 512 66 0F W1 58 r VADDPD zmm1 k1 z zmm2 zmm3 m
  • X86 预取优化:“计算 goto”线程代码

    我有一个相当重要的问题 我的计算图有循环和多个 计算路径 我没有制作一个调度程序循环 其中每个顶点将被一一调用 而是将所有预先分配的 框架对象 放置在堆中 代码 数据 这有点类似于线程代码 甚至更好 CPS 只是在堆中跳转 执行代码 每个代
  • 为什么 clang 使用 -O0 生成低效的 asm(对于这个简单的浮点和)?

    我正在 llvm clang Apple LLVM 版本 8 0 0 clang 800 0 42 1 上反汇编此代码 int main float a 0 151234 float b 0 2 float c a b printf f c
  • 使用 Turbo C 编译并链接到 .com 文件

    我正在尝试使用 Turbo C 编译器和链接器编译一个简单的程序并将其链接到 DOS com 文件 我尝试了我能想到的最简单的 C 程序 void main Turbo C 链接器中是否有链接到 com 文件的命令行参数 我从链接器收到的错
  • 错误 LNK2019:函数 main 中引用的外部符号无法解析

    我正在尝试在 C 中运行我的简单汇编代码 我只有两个文件 cpp 文件和 asm 文件 编译时出现错误 见下文 如果有人可以提供帮助 我将不胜感激 这是我的 main cpp 文件 include
  • 长多字节 NOP:通常理解的宏或其他符号

    x86 和 x86 64 处理器不仅具有单字节 这不是什么大秘密NOP指令 还包括各种类型的多字节类 NOP 指令 这些是我设法找到的 AMD 推荐 参考 AMD 系列 15h 处理器的 AMD 软件优化指南 文档 47414 http s
  • 从类模板参数为 asm 生成唯一的字符串文字

    我有一个非常特殊的情况 我需要为类模板中声明的变量生成唯一的汇编程序名称 我需要该名称对于类模板的每个实例都是唯一的 并且我需要将其传递给asm关键字 see here https gcc gnu org onlinedocs gcc 12

随机推荐

  • Java 中的额外导入会减慢代码加载时间吗?

    向 Java 代码中添加更多 import 语句是否可能会减慢将类加载到 JVM 中所需的时间 不 导入仅在编译中用于查找类引用 添加未使用的导入 它们不会执行任何操作 换一种方式 import java util 只是意味着你可以写 Ma
  • GQL中有OR运算符吗?

    我不知道这里是否有人问过这个问题 我看到了几个关于 like 运算符的问题 但我不确定这是否是我正在寻找的 抱歉我在这方面是菜鸟 但我正在从 MySQL 迁移到 Google App Engine 并且想知道 GQL 中是否有类似于 MyS
  • C++:如何将存储在局部变量中的函数指针作为模板参数传递

    using namespace std float test1 float i return i i int test2 int i return i 9 struct Wrapper typedef void wrapper type i
  • 是否可以从通用特征实现中排除某种类型?

    我正在尝试用毯子创建一个错误类型From实施任何Error 但是由于这种类型本身就是一个Error我遇到冲突 pub struct ApiError pub i64 pub String impl
  • 在cypress中捕获websocket请求

    我试图捕获测试期间发生的所有请求 我的应用程序使用 WebSocket 并且使用拦截命令我无法捕获 wss 请求 有什么办法可以做到这一点吗 我认为拦截命令不能直接捕获网络套接字 一种方法是观察 ws 通信的结果 如下所示使用 Cypres
  • 如何使用jq提取json值子字符串

    我有这个 json temperature 21 humidity 12 3 message Today ID 342 is running 我想使用jq来获取这个json temp 21 hum 12 3 id 342 正如你所看到的 我
  • 将 WPF 单选按钮设置为具有正确 IsEnabled 行为的切换按钮

    我需要将一些分组单选按钮设置为切换按钮 为此 我将以下样式应用于单选按钮 Style StaticResource x Type ToggleButton 这给了我想要的风格 但我注意到一个恼人的副作用 我需要能够在禁用控件时更改所选按钮
  • 使用android应用程序的http post方法发送json对象

    我正在尝试将 JSON 对象发送到我的 php web 服务 我已经提到了这个网址 http www josecgomez com 2010 04 30 android accessing restfull web services usi
  • 根据其他列设置列的值

    我有一个数据框 如下所示 ID Score New ID New Score 123 5 456 456 1 789 789 0 123 我想为 New ID 列提供相同的分数 只是顺序不同 期望的结果 ID Score New ID Ne
  • 颤动中的多个依赖下拉菜单

    我正在尝试在颤动上构建多个依赖的下拉菜单 第二个依赖于第一个 这是我实现的下拉列表的代码 Container child new DropdownButton
  • C# CreateSymbolicLink 不遵循共享访问

    我不确定这只是 C 问题还是 Windows 限制 我有一台运行我的程序的服务器 它在共享文件夹中创建符号链接 我可以通过此链接从具有正常磁盘路径和共享路径的服务器进行访问 如果我尝试与其他电脑访问同一共享 我将无法访问链接的文件 我确实可
  • Pandas如何按列按间隔分割数据框

    我有一个巨大的数据框 其中有一个名为的日期时间类型列dt 数据框排序基于dt已经 我想根据以下内容将数据帧拆分为多个数据帧dt 每个数据帧包含行1 hr range Split dt text 0 20160811 11 05 a 1 20
  • IE 下的 Http 请求速度变慢

    在我的 javascript 应用程序中工作时 我注意到使用 IE 11 时 相同的 ajax 请求时间最多延长 10 倍 响应大小完全相同 12 6KB 我看到的唯一区别是 IE 添加 Pragma no cache 不是铬 Chrome
  • 在 docker 容器内运行 vite 开发服务器

    我有一个 Vue cli 应用程序 我正在尝试将其转换为 vite 我正在使用 Docker 来运行服务器 我看了几个教程 并让 vite 在开发模式下运行 没有错误 但是 浏览器无法访问该端口 也就是说 当我在 macbook 的命令行上
  • Git - 如何压缩对被忽略文件的更改而不丢失这些更改?

    我想使用 git 保存应用程序随时间使用的实际依赖项的历史记录 其保真度比我从包管理器获得的保真度更高 我正在使用这些分支 master 仅源代码 依赖于 gitignore 构建 源代码和依赖项 build TIMESTAMP 用于强制提
  • 从 Silverlight OOB 访问注册表

    我可以访问吗Registry from Silverlight Out Of Browser 我只想搜索 读取键并获取键值对 这可能吗 或者 有没有其他方法 例如运行powershell script 或启动其他一些 exe 来了解这些值
  • Python @property 与方法性能 - 使用哪一个?

    我编写了一些使用对象属性的代码 class Foo def init self self bar baz myFoo Foo print myFoo bar 现在我想做一些花哨的计算来返回bar 我可以用 property使方法充当属性ba
  • Ionic 4无法导入自定义组件不是已知元素

    我是 Ionic 新手 我想创建一个带有可扩展项目的自定义列表视图 如下链接 https www joshmorony com creating an accordion list in ionic https www joshmorony
  • 相当于使用 for-loop 代替 do-while-loop

    我想知道 c 中等效的 for 循环或任何其他循环组合是什么 而不是使用 do while 循环 任何类型的循环都可以通过无限 永远 循环和条件循环的组合来构造break陈述 例如 要转换 do
  • 在 REP MOVSW 之前 PUSH CS / POP DS 的目的是什么?

    为什么在下面的代码中我们压入代码段 PUSH CS 然后将其弹出到数据段 POP DS 我将这些行明确指定为 line1 和 line2 请告诉我 MOVSW 在这里是如何工作的 IF HIGHMEMORY PUSH DS MOV BX D