MASM字符串指令-在实模式下,前一LEA上的段寄存器覆盖



对于8086,可以覆盖源索引SI的段,以便使用ES而不是DS。在一本书(旧的Scanlon(中,我发现了以下MASM代码:

LEA SI,ES:HERE
LEA DI,ES:THERE
MOVSB

由于LEA仅检索存储器地址的OFFSET(8086的16位(,MOVSB如何知道SI指的是ES段而不是DS段?LEA是否正在更改SI的默认段?在我发现的许多页面和手册中,我没有读过任何关于这方面的内容。

该代码看起来是错误的。如果没有段覆盖前缀,movsb将始终使用DS:SIES:DI。除非您必须担心古代处理器的错误数据,否则您可以通过为movsb提供段覆盖前缀来使此代码正常工作。CCD_ 5将告诉它使用CCD_ 6而不是CCD_。CCD_ 8总是拷贝到CCD_ 9;没有段覆盖前缀会改变它。

如果保证DS在这个位置等于ES,那么代码实际上可能是正确的。旧的汇编程序有自己的优点,有时必须使用有趣的段重写来让汇编程序满意。

我在DOSBOX中安装了MASM6.11,并做了一些实验。以下是数据段的内存映射:

0000               dseg segment para public 'data'
0000 41 42 43 44   src db 'ABCD'
0004               dseg ends
0000               eseg segment para public 'data'
0000 5A 5A 5A 5A   dummy db 'ZZZZ'
0004 31 32 33 34   dst db '1234'
0008               eseg ends
0000               cseg segment para public 'code'
assume cs:cseg, ds:dseg, es:eseg

结果是代码:

LEA SI,ES:HERE
LEA DI,ES:THERE
MOVSB

是错误的:根本不考虑分段,它在任何情况下都从DS复制到ES(OP-CODE是A4(:

8D 36 0000 R
8D 3E 0004 R
A4

为了实现从ES到ES的复制,您需要编写:

LEA SI,ES:HERE
LEA DI,ES:THERE
MOVS ES:THERE, ES:HERE

翻译过来就是:

8D 36 0000 R
8D 3E 0004 R
26: A4

SyntaxES MOVSBES:MOVSB我在回答中读到的答案不适用于MASM 6.11(但它们实际上对应于它的翻译:26是ES的代码(。

最新更新