i386 指令前缀
i386 可以寻址 8 位、16 位、32 位,工作在两种模式下 16 位实模式和 32 位保护模式。
16 位实模式是同 8086 80286 CPU 兼容的,而 80286/8086 并不支持 32 位寻址。
在 80286/8086 下只能 8 位或 16 位寻址。例如 MOV reg,imm 指令为:1011wrrr data。
其中 w 指定操作的寄存器 rrr 是 8 位寄存器还是 16 位寄存器。
w = 0 时,rrr 为 AL CL DL BL AH CH DH BH 8 个 8 位寄存器。
w = 1 时,rrr 为 AX CX DX BX SP BP SI DI 8 个 16 位寄存器。
但是 i386(80386DX 80486 …) 也可以在实模式下操作 32 位寄存器,同时保留对 80286/8086 指令的兼容。办法就是使用指令前缀。
i386 指令前缀有两个:表征操作数前缀 66h 和表征地址长度前缀 67h。
使用 66h 前缀时,指令中的 16 位寄存器就自动扩展为 32 位寄存器
这样,在 16 位模式下 MOV 32reg,imm 就是 66h 10111rrr data,这时 w = 1。
rrr 分别就是 EAX ECX EDX EBX ESP EBP ESI EDI 8 个 32 位寄存器。
同样,前缀 67h 使用时就是对指令中的地址进行 32 位扩展。
当 i386 进入 32 位保护模式后,默认操作的 w = 1 寄存器就是 32 位寄存器,不再需要指令前加 66h 前缀。
而此时操作 16 位寄存器时,就必须在指令前加上 66h 前缀了。
所以,在汇编代码中通常需要指定当前的系统模式。
比如 NASM 中的 bits 16 指定默认的是 16 位模式,bits 32 是 32 位模式。
发表评论