gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-12-02 19:08:51 27 4
gpt4 key购买 nike

为什么在下面的代码中我们压入代码段(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 然后恢复它看起来是在 rep movsw 上使用 CS 覆盖前缀的低效替代方案。

A segment override can change the source for movswDS:SICS:SI。 (ES:DI 的目的地无法覆盖)。

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

<小时/>

此代码正在执行 memcpy(dst, code_segment, sizeof(code_segment)),其中 dst 段:偏移量为 (BX + 16):0rep movsw 之前的指令设置 DS = BX+16 并设置 DI=0。

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

显然这个汇编器不支持像 ret farretf 这样的语法,所以他们必须通过声明一个来汇编一个远 ret 指令proc far 围绕 ret 指令。 AAA 对于该过程来说是一个非常奇怪的名称,因为 aaa is also a valid x86 instruction mnemonic (ASCII Adjust after Addition) .

因此,在我们刚刚制作的代码副本中的 SECONDRELOCATION: 标签处继续执行。

<小时/>

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

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

无论如何,重点可能是将代码重新定位到 HIGMEM 中,留下低内存以供无法使用 HIMEM 的程序使用。

关于assembly - 在 REP MOVSW 之前 PUSH CS/POP DS 的目的是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53604760/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com