STOSB是否有使用额外段的特殊原因?

1 assembly memory-segmentation x86-16

我已经读过这样的STOSB函数:

ES:[DI] <-- AL
Run Code Online (Sandbox Code Playgroud)

如果DF = 0增量DI否则递减DI.

  • 那么为什么STOSB不改变DS:[DI]呢?
  • 是否有使用额外细分的特殊目的?
  • 在大多数字符串指令中,我们使用额外段 为什么?

zx4*_*485 5

那么为什么STOSB不会改变DS:[DI]

因为这个定义会与LODSB已经使用的定义相冲突DS:[SI].使用单独的段寄存器可以提供更大的灵活性.

是否有使用额外细分的特殊目的?

是.您可以在处理段时轻松地在段之间传输字节.例如,你可以使用一个LODSB装载AL从DS:[SI],修改AL,然后将其存储到不同的段,该附加段,与STOSB使用ES:[DI].在8086中,它具有16位段大小和20位地址空间,这非常有用.

示出了另一种指令是REP MOVSB指令,其复制的字节序列(其在长度CX)从DS:[SI]到ES:[DI].

(如果你没有需要检查每一个字节,你复制它,你只需使用rep movsb或rep movsw比更好的性能lods/ stos在一个循环中.)

在大多数字符串指令中,我们使用额外段 为什么?

嗯,不是大多数,但可能大约一半.使用另一个段寄存器可以快速访问不同的段 - 您不仅可以在一个64KB段中处理数据,而且不必DS在每次访问不同段之前更改寄存器.

stos和movs写es:[di],这是有道理的,因为DI是"目标索引"寄存器.

cmps并且scas读取es:[di],这可能是令人惊讶的,scas因为它只有一个内存操作数,所以你可能期望它从ds:[si]类似的读取lods.特别是因为SCASB设置了标志AL - [mem],而不是相反,所以它就像是一个cmp内存是正确的操作数(源),而不是左(目标).喜欢cmp al, es:[di].

也许8086指令集的架构师想象了一个循环的用例,它在段之间实现lods和scas实现strcmp.