mov eax,10h
mov ds,ax
这段代码是linux内核system_call.s里面拿出来的。
我弄不明白,为什么第一句给eax赋值,然后下面却用ax去给别的寄存器赋值呢?
为什么第一句不直接用ax呢?
------解决方案--------------------
http://www.agner.org/optimize 的 2. 里有这么一段:
Instructions with multiple prefixes can slow down decoding. The maximum number of prefixes that an instruction can have without slowing down decoding is 1 on 32-bit Intel processors, 2 on Intel P4E processors, 3 on AMD processors, and unlimited on Core2. Avoid address size prefixes. Avoid operand size prefixes on instructions with an immediate operand. For example, it is preferred to replace MOV AX,2 by MOV EAX,2.
------解决方案--------------------
之所以要
mov eax,10h
mov ds,ax
而不是
mov ax,10h
mov ds,ax
是因为在32位模式下,后者会导致所谓的Partial Register Stall,指令执行时间延长。虽然这一两个时钟周期的延迟微不足道,但是linux内核的维护者应该是精益求精的优化论者。:)
------解决方案--------------------
32 Bits 里使用 16 Bits 寄存器,要加前缀,表示使用16Bits寄存器,
mov ax,10h
比
mov eax,10h
指令长度多一个字节,取指令可能要,多用一个时钟周期。
同样
16 Bits 里使用 32 Bits 寄存器,要加前缀,表示使用16Bits寄存器,
32Bits的
mov eax,10h
和
16 Bits 的
mov ax,10h
指令完全一样。
这个指令系统这样设计,导致这个问题。
为了区分32Bits,和16Bits,寄存器,
当指令的Bits和寄存器,不一致的时候,就要加前缀,以示区别。
------解决方案--------------------
32Bits 使用16Bits寄存器,加前缀 0x66