对于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:SI
和ES: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 MOVSB和ES:MOVSB我在回答中读到的答案不适用于MASM 6.11(但它们实际上对应于它的翻译:26是ES的代码(。