1 assembly memory-segmentation x86-16
我已经读过这样的STOSB函数:
ES:[DI] <-- AL
Run Code Online (Sandbox Code Playgroud)
如果DF = 0增量DI否则递减DI.
STOSB不改变DS:[DI]呢? 那么为什么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.