问题描述
我正在尝试了解GAS对.code16的行为.在手册中,对于16位部分,对于32位操作数或指令,似乎会为指令编码生成一个66H操作数替代前缀.那是不是
I'm trying to understand GAS's behavior of .code16.From the manual, it seems in 16-bit section, for 32-bit operands or instructions, a 66H operand override prefix will be produced for the instruction encoding. Does that mean
.code16
movw %eax, %ebx
在这种模式下合法吗?那么代码不能在16位处理器上运行吗?
is legal in such mode? Then the code cannot run on 16-bit processor?
推荐答案
这些是80386+的法律说明.从80386开始,我们可以使用操作数大小和地址大小覆盖前缀.这些前缀可以与16位地址模式和32位地址模式结合使用.另外,它可以与实际地址模式,受保护模式以及虚拟86模式一起使用.这些前缀反转了代码段中一条指令的默认操作数大小和/或地址大小.默认操作数大小和地址大小由代码段描述符中的D标志指定(或者,如果没有GDT/LDT,则在BIOS的POST处理完成后,我们将成为16位地址模式.)
These are legal instructions for 80386+.Starting with the 80386 we can use operandsize- and addresssize- override prefixes.Those prefixes can be used in combination with the 16 bit address mode and with the 32 bit address mode. Additional it can be used with the real addressmode and with the protected mode and the virtual 86 mode. Those prefixes reverse the default operandsize and/or the addresssize for one instruction in the codesegment. The default operandsize and the addresssize is specified by the D flag in the code-segment descriptor(or if there is no GDT/LDT, then we become the 16 bit addressmode after the POST-process of the bios is done.)
如果要使用32位操作数和/或32位地址,则必须使用16位地址模式添加这些前缀.没有这些前缀,我们只能在16位地址模式下使用16位地址/操作数.
With the 16 bit addressmode we have to add those prefixes, if we want to use 32 bit operands and/or 32 bit addresses. Without those prefixes we can only use 16 bit addresses/operands in the 16 bit addressmode.
如果要使用32位操作数和/或32位地址,则在32位地址模式下,我们必须从代码中省略那些前缀.如果将这些前缀添加到代码中,则可以在32位地址模式下使用16位地址/操作数.
With the 32 bit addressmode we have to leave out those prefixes from our code, if we want to use 32 bit operands and/or 32 bit addresses. And if we add those prefixes to our code, then we can use 16 bit addresses/operands in the 32 bit addressmode.
指令前缀可用于覆盖代码段的默认操作数大小和地址大小.这些前缀可以在实地址模式以及保护模式和虚拟8086模式中使用.操作数大小或地址大小前缀仅在指令持续时间内更改大小.
Instruction prefixes can be used to override the default operand size and address size of a code segment. These prefixes can be used in real-address mode as well as in protected mode and virtual-8086 mode. An operand-size or address-size prefix only changes the size for the duration of the instruction.
以下两个指令前缀允许在一个段中混合使用32位和16位操作:•操作数大小前缀(66H)•地址大小前缀(67H)
The following two instruction prefixes allow mixing of 32-bit and 16-bit operations within one segment:•The operand-size prefix (66H)•The address-size prefix (67H)
这些前缀反转了由代码段描述符中的D标志选择的默认大小.例如,处理器可以以下四种方式中的任何一种来解释(MOV mem,reg)指令:•在32位代码段中:-使用32位有效地址将32位从32位寄存器移至内存.—如果在操作数大小前缀之前添加16位,则使用32位有效地址将16位从16位寄存器移至内存.—如果在其后加上地址大小前缀,则使用16位有效地址将32位从32位寄存器移至存储器.如果在地址大小前缀和操作数大小前缀之前都添加了16位有效地址,则将16位从16位寄存器移到内存中.
These prefixes reverse the default size selected by the D flag in the code-segment descriptor. For example, the processor can interpret the (MOV mem, reg) instruction in any of four ways:•In a 32-bit code segment:—Moves 32 bits from a 32-bit register to memory using a 32-bit effective address.—If preceded by an operand-size prefix, moves 16 bits from a 16-bit register to memory using a 32-bit effective address.—If preceded by an address-size prefix, moves 32 bits from a 32-bit register to memory using a 16-bit effective address.—If preceded by both an address-size prefix and an operand-size prefix, moves 16 bits from a 16-bit register to memory using a 16-bit effective address.
•在16位代码段中:-使用16位有效地址将16位从16位寄存器移至内存.—如果在操作数大小前缀之前添加32位,则使用16位有效地址将32位从32位寄存器移至内存.—如果在前面加上地址大小前缀,则使用32位有效地址将16位从16位寄存器移至存储器.如果在地址大小前缀和操作数大小前缀之前都添加了地址,则使用32位有效地址将32位从32位寄存器移到内存中.
•In a 16-bit code segment:—Moves 16 bits from a 16-bit register to memory using a 16-bit effective address.—If preceded by an operand-size prefix, moves 32 bits from a 32-bit register to memory using a 16-bit effective address.—If preceded by an address-size prefix, moves 16 bits from a 16-bit register to memory using a 32-bit effective address.—If preceded by both an address-size prefix and an operand-size prefix, moves 32 bits from a 32-bit register to memory using a 32-bit effective address.
前面的示例表明,任何指令都可以生成操作数大小和地址大小的任意组合,而不管该指令是在16位段还是32位段中.通常,根据以下条件为代码段选择16位或32位默认值:•性能-尽可能使用32位代码段.它们在P6系列处理器上的运行速度比16位代码段要快得多,而在较早的IA-32处理器上则要快一些.•代码段将在其上运行的操作系统—如果该操作系统是16位操作系统,则它可能不支持32位程序模块.•操作模式-如果将代码段设计为以实地址模式,virtual-8086模式或SMM运行,则它必须是16位代码段.•与早期IA-32处理器的向后兼容性—如果代码段必须能够在Intel 8086或Intel 286处理器上运行,则它必须是16位代码段.
The previous examples show that any instruction can generate any combination of operand size and address size regardless of whether the instruction is in a 16- or 32-bit segment. The choice of the 16- or 32-bit default for a code segment is normally based on the following criteria:•Performance — Always use 32-bit code segments when possible. They run much faster than 16-bit code segments on P6 family processors, and somewhat faster on earlier IA-32 processors.•The operating system the code segment will be running on — If the operating system is a 16-bit operating system, it may not support 32-bit program modules.•Mode of operation — If the code segment is being designed to run in real-address mode, virtual-8086 mode, or SMM, it must be a 16-bit code segment.•Backward compatibility to earlier IA-32 processors — If a code segment must be able to run on an Intel 8086 or Intel 286 processor, it must be a 16-bit code segment.
代码段描述符中的D标志确定代码段指令的默认操作数大小和地址大小. (在不使用段描述符的实地址模式和虚拟8086模式下,默认值为16位.)设置了D标志的代码段是32位段;默认值为16位. D标志清零的代码段是16位的段.
The D flag in a code-segment descriptor determines the default operand-size and address-size for the instructions of a code segment. (In real-address mode and virtual-8086 mode, which do not use segment descriptors, the default is 16 bits.) A code segment with its D flag set is a 32-bit segment; a code segment with its D flag clear is a 16-bit segment.
可执行代码段.该标志称为D标志,它指示段中指令引用的有效地址和操作数的默认长度.如果设置了该标志,则假定使用32位地址和32位或8位操作数;否则,将使用默认值.如果清楚,则假定使用16位地址和16位或8位操作数.指令前缀66H可以用来选择默认值以外的操作数大小,而前缀67H可以用来选择默认值以外的地址大小.
Executable code segment. The flag is called the D flag and it indicates the default length for effective addresses and operands referenced by instructions in the segment. If the flag is set, 32-bit addresses and 32-bit or 8-bit operands are assumed; if it is clear, 16-bit addresses and 16-bit or 8-bit operands are assumed.The instruction prefix 66H can be used to select an operand size other than the default, and the prefix 67H can be used select an address size other than the default.
可以在实地址模式程序中使用32位操作数前缀来执行32位形式的指令.该前缀还允许实地址模式程序使用处理器的32位通用寄存器.可以在实地址模式程序中使用32位地址前缀,从而允许32位偏移.
The 32-bit operand prefix can be used in real-address mode programs to execute the 32-bit forms of instructions. This prefix also allows real-address mode programs to use the processor’s 32-bit general-purpose registers.The 32-bit address prefix can be used in real-address mode programs, allowing 32-bit offsets.
以Intel386处理器开头的IA-32处理器可以使用地址覆盖前缀生成32位偏移量.但是,在实地址模式下,如果不引起异常,则32位偏移量的值不得超过FFFFH.
The IA-32 processors beginning with the Intel386 processor can generate 32-bit offsets using an address override prefix; however, in real-address mode, the value of a 32-bit offset may not exceed FFFFH without causing an exception.
汇编程序用法:如果定义了将在实地址模式下运行的代码段,则必须将其设置为USE 16属性.如果在此代码段的指令中使用32位操作数(例如,MOV EAX,EBX),则汇编器会自动为该指令生成一个操作数前缀,即使处理器执行32位操作,该指令也将强制处理器执行32位操作默认的代码段属性为16位.
Assembler Usage:If a code segment that is going to run in real-address mode is defined, it must be set to a USE 16 attribute. If a 32-bit operand is used in an instruction in this code segment (for example, MOV EAX, EBX), the assembler automatically generates an operand prefix for the instruction that forces the processor to execute a 32-bit operation, even though its default code-segment attribute is 16-bit.
32位操作数前缀允许实地址模式程序使用32位通用寄存器(EAX,EBX,ECX,EDX,ESP,EBP,ESI和EDI).
The 32-bit operand prefix allows a real-address mode program to use the 32-bit general-purpose registers (EAX, EBX, ECX, EDX, ESP, EBP, ESI, and EDI).
在段寄存器和32位通用寄存器之间以32位模式移动数据时注册时,奔腾Pro处理器不需要使用16位操作数大小的前缀;但是,某些汇编程序确实需要此前缀.处理器假定16个最低有效位通用寄存器的位是目标或源操作数.移动时从段选择器到32位寄存器的值,处理器将填充两个高位字节寄存器为零.
When moving data in 32-bit mode between a segment register and a 32-bit general-purposeregister, the Pentium Pro processor does not require the use of a 16-bit operand size prefix;however, some assemblers do require this prefix. The processor assumes that the 16 least-significantbits of the general-purpose register are the destination or source operand. When moving avalue from a segment selector to a 32-bit register, the processor fills the two high-order bytes ofthe register with zeros.
3.3.2. 32位和16位地址和操作数大小可以将处理器配置为32位或16位地址和操作数大小.带32位地址和操作数的大小,最大线性地址或段偏移为FFFFFFFFH(2 ^ 32-1),操作数大小通常为8位或32位.具有16位地址和操作数大小,最大线性地址或段偏移量为FFFFH(2 ^ 16-1),操作数大小通常为8位或16位.使用32位寻址时,逻辑地址(或远指针)由16位段组成选择器和32位偏移量;当使用16位寻址时,它包含一个16位段选择器和16位偏移量.指令前缀允许临时覆盖默认地址和/或操作数的大小在一个程序中.在保护模式下运行时,当前执行代码的段描述符段定义默认地址和操作数大小.段描述符是系统数据应用程序代码通常不可见的结构.汇编程序指令允许默认要为程序选择的地址和操作数大小.然后安装汇编器和其他工具适当地为代码段设置段描述符.在实地址模式下运行时,默认的寻址和操作数大小为16位.一个地址大小覆盖可在实地址模式下使用,以启用32位寻址.但是,那最大允许的32位线性地址仍为000FFFFFH(2 ^ 20-1).
3.3.2. 32-Bit vs. 16-Bit Address and Operand SizesThe processor can be configured for 32-bit or 16-bit address and operand sizes. With 32-bitaddress and operand sizes, the maximum linear address or segment offset is FFFFFFFFH(2^32-1), and operand sizes are typically 8 bits or 32 bits. With 16-bit address and operand sizes,the maximum linear address or segment offset is FFFFH (2^16-1), and operand sizes are typically8 bits or 16 bits.When using 32-bit addressing, a logical address (or far pointer) consists of a 16-bit segmentselector and a 32-bit offset; when using 16-bit addressing, it consists of a 16-bit segment selectorand a 16-bit offset.Instruction prefixes allow temporary overrides of the default address and/or operand sizes fromwithin a program.When operating in protected mode, the segment descriptor for the currently executing codesegment defines the default address and operand size. A segment descriptor is a system datastructure not normally visible to application code. Assembler directives allow the defaultaddressing and operand size to be chosen for a program. The assembler and other tools then setup the segment descriptor for the code segment appropriately.When operating in real-address mode, the default addressing and operand size is 16 bits. Anaddress-size override can be used in real-address mode to enable 32-bit addressing; however, themaximum allowable 32-bit linear address is still 000FFFFFH (2^20-1).
3.6.运营规模和地址规模属性当处理器以保护模式执行时,每个代码段都有一个默认的操作数大小属性和地址大小属性.这些属性用D(默认大小)选择代码段的段描述符中的标志(请参见第3章,保护模式内存)英特尔架构软件开发人员手册,第3卷)中的管理".当D设置标志,选择32位操作数大小和地址大小属性;当标记清除时,选择16位大小属性.当处理器以实地址模式执行时,virtual-8086模式或SMM(系统管理模式),默认操作数大小和地址大小属性始终为16位.操作数大小属性选择指令对其进行操作的操作数的大小.当...的时候有效的是16位操作数大小属性,操作数通常可以是8位或16位,并且启用32位操作数大小属性时,操作数通常可以是8位或32位.address-size属性选择用于寻址存储器的地址大小:16位或32位.当16位地址大小属性生效时,段偏移量和位移为16位.此限制将可寻址的段的大小限制为64 KB.当...的时候有效的是32位的address-size属性,段的偏移量和位移是32位,允许最多可寻址4 GB的段.默认的操作数大小属性和/或地址大小属性可以为特定的值覆盖通过向指令添加操作数大小和/或地址大小前缀来实现指令(请参见《英特尔架构软件开发人员手册》第2章中的指令前缀",第3卷).该前缀的作用仅适用于其附加的指令.表3-1显示了有效的操作数大小和地址大小(在保护模式下执行时)取决于D标志的设置以及操作数大小和地址大小前缀.
3.6. OPERAND-SIZE AND ADDRESS-SIZE ATTRIBUTESWhen the processor is executing in protected mode, every code segment has a default operand-sizeattribute and address-size attribute. These attributes are selected with the D (default size)flag in the segment descriptor for the code segment (see Chapter 3, Protected-Mode MemoryManagement, in the Intel Architecture Software Developer’s Manual, Volume 3). When the Dflag is set, the 32-bit operand-size and address-size attributes are selected; when the flag is clear,the 16-bit size attributes are selected. When the processor is executing in real-address mode,virtual-8086 mode, or SMM (System-Management-Mode), the default operand-size and address-size attributes are always 16bits.The operand-size attribute selects the sizes of operands that instructions operate on. When the16-bit operand-size attribute is in force, operands can generally be either 8 bits or 16 bits, andwhen the 32-bit operand-size attribute is in force, operands can generally be 8 bits or 32 bits.The address-size attribute selects the sizes of addresses used to address memory: 16 bits or 32bits. When the 16-bit address-size attribute is in force, segment offsets and displacements are 16bits. This restriction limits the size of a segment that can be addressed to 64 KBytes. When the32-bit address-size attribute is in force, segment offsets and displacements are 32 bits, allowingsegments of up to 4 GBytes to be addressed.The default operand-size attribute and/or address-size attribute can be overridden for a particularinstruction by adding an operand-size and/or address-size prefix to an instruction (see"Instruction Prefixes" in Chapter 2 of the Intel Architecture Software Developer’s Manual,Volume 3). The effect of this prefix applies only to the instruction it is attached to.Table 3-1 shows effective operand size and address size (when executing in protected mode)depending on the settings of the D flag and the operand-size and address-size prefixes.
德克
这篇关于16位模式下的操作数大小前缀的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!