当您使用内存覆盖前缀但所有操作数都是寄存器时会发生什么?

问题描述:

当您使用内存覆盖前缀但所有操作数都是寄存器时会发生什么?当您使用内存覆盖前缀但所有操作数都是寄存器时会发生什么?

因此,假设您的代码为mov eax, ebxadd eax, ebx,默认值为32位,但您使用67h覆盖。

处理器如何处理这种情况?

+2

'66'是操作数大小前缀,因此使得它成为'MOV AX,bx'。你的意思是'67'地址大小前缀? –

+0

是的,我编辑了原始问题。不,等待我的意思是最初的问题。整个过程就是将内存前缀与内存操作数混合在一起。 – matrix2

+0

'66'不是一个“记忆”前​​缀。 '89 d8'是'mov eax,ebx'。 '66 89 d8'是'mov ax,bx'(32或64位模式,否则66前缀使操作数大小为32位而不是默认值16)。这就是你想问的问题,或者你真的想知道使'mov eax,[ebx]'成为'mov eax,[bx]'的'67'地址长度前缀。 (或在64位模式下,'mov eax,[rbx]'到'mov eax,[ebx]'。) –

英特尔®软件开发人员手册*第2卷第2.1节详细介绍了每个指令前缀的行为。它表示使用地址大小前缀(67h)和没有内存操作数的指令被保留,并可能导致不可预知的行为。

操作数大小前缀(66h)可用于在16位和32位操作数大小之间切换,也可用作特定SSE2/SSE3/SSSE3/SSE4指令的强制性前缀。其他用途保留并可能导致不可预知的行为。

段覆盖前缀由任何分支指令保留。

* https://software.intel.com/en-us/articles/intel-sdm

+1

在真实的硬件上,不适用的前缀将被忽略。这就是为什么他们是“保留”而不是“原因#UD”。除了'lock',它不适用''UD'时。 –

+0

@ peter但英特尔文档中“保留”意味着您可以使用它,它会被忽略?我会认为这意味着“不要使用它,任何事情都可能发生”。现在看来,在实践中,保留前缀的使用往往被忽略,这对英特尔来说很方便,因为他们之后可以使用以前没有意义的前缀来定义新的行为,并且在那时还记录在早期芯片上它也没问题(忽略)。尽管其他保留的行为可能非常好。 – BeeOnRope

+0

@BeeOnRope:不,我不这么认为,因为他们通常只记录未来的保证,而不是目前的CPU如果不想保证将来会做什么的具体细节。就像你说的那样,他们只会记录事实之后的忽略行为,比如'tzcnt' /'bsf'。然而,有一些例子,比如'rep ret',在不破坏大量gcc编译的二进制文件的情况下不能重新使用,所以[我不希望任何主流CPU重新使用它几十年。](https:// *.com/questions/20526361/what-does-rep-ret-mean/32347393#32347393)。 –