|
发表于 2024-1-23 09:01:52
|
显示全部楼层
简单来说就是它们互斥。
INTEL 8086~80286只有8位和16位寄存器,它的机器指令只能操作8位或者16位数据,访问内存时,只能使用16位段内偏移量(有效地址)。后来称之为16位指令。
1985年的80386是INTEL的第一款32位处理器,有保护模式,支持平坦内存模型,所以,它需要添加能够操作32位数据的机器指令,也需要添加能够使用32位有效地址的机器指令。后来称之为32位指令。
INTEL公司应该也想在同一相框架下添加32位指令。即,将16位指令和32位指令混合在一起编码。但面临的问题是指令众多,指令集急剧膨胀,指令长度会大大增加,效率降低。
因此,如果能按照不同的工作模式,让32位指令和16位指令共用机器码,是不错的编码方案。比如
89 C8
当处理器工作在16位模式下,即,默认操作尺寸是16位的,它将该机器指令看成是
mov ax, cx
相反地,如果处理器工作在32位模式,即,默认操作尺寸是32位的,它把该机器指令看成是
mov eax, ecx
但是,如果当前默认的操作尺寸是16位的,而我们又想执行32位的
mov eax, ecx
或者,如果当前默认的操作尺寸是32位的,而我们又想执行16位的
mov ax, cx
该怎么办呢?很简单,只需要添加反转操作数尺寸的前缀0x66即可,就象这样:
66 89 C8
如此一来,如果当前默认的操作尺寸是16位的,即,CS描述符高速缓存器中的D位是0,则机器指令
89 C8
被处理器当成是16位操作尺寸的汇编指令
mov ax, cx
来执行,而机器指令
66 89 C8
被处理器当成是32位操作尺寸的汇编指令
mov eax, ecx
来执行。
相反地,如果当前默认的操作尺寸是32位的,即,CS描述符高速缓存器中的D位是1,则机器指令
89 C8
被处理器当成是32位操作尺寸的汇编指令
mov eax, ecx
来执行,而机器指令
66 89 C8
被处理器当成是16位操作尺寸的汇编指令
mov ax, cx
来执行。
|
|