我已经了解到STOSB
的功能如下:
ES:[DI] <-- AL
如果DF = 0
递增DI
,否则递减DI
。
STOSB
不更改DS:[DI]
? 答案 0 :(得分:4)
那为什么STOSB不会更改DS:[DI]
因为此定义将与已经使用LODSB
的{{1}}的使用相冲突。使用单独的段寄存器可为您提供更大的灵活性。
使用额外的细分受众群是否有特殊目的?
是的。您可以在处理段时轻松地在段之间传输字节。例如,您可以使用DS:[SI]
的{{1}}加载LODSB
,修改AL
,然后将其存储到其他段中,即 Extra Segment ,其中DS:[SI]
使用AL
。在8086中,其16位段大小和20位地址空间确实有用。
说明使用的另一条指令是STOSB
指令,该指令将字节序列(其长度在ES:[DI]
中)从REP MOVSB
复制到CX
。
(如果复制时不需要检查每个字节,只需使用DS:[SI]
或ES:[DI]
比rep movsb
/ rep movsw
获得更好的性能循环。)
在大多数字符串指令中,我们使用额外的段。为什么?
嗯,不是大多数,但大概是一半。使用另一个段寄存器给您带来了快速访问不同段的优点-您不仅限于仅在一个64KB段中处理数据,而且不必在每次访问不同段之前更改lods
寄存器。>
stos
和DS
写入stos
,这是有道理的,因为movs
是“目标索引”寄存器。
es:[di]
和DI
从cmps
读取,这对于scas
可能是令人惊讶的,因为它只有一个内存操作数,因此您可能希望它从{{1 }}就像es:[di]
。特别是因为SCASB从scas
设置标志,而不是相反,所以就像ds:[si]
,其中内存是右操作数(源)而不是左操作数(目标)。像lods
。
也许8086指令集的设计者想象了一个循环的用例,该循环执行AL - [mem]
和cmp
来实现段之间的cmp al, es:[di]
。