我一直在关于编写程序集的几个例子,他们使用一个临时寄存器来传递一个段值寄存器的立即值。为什么需要在将立即数放入段寄存器之前将其寄存在某个寄存器中?
例子:
为什么使用临时寄存器将值传递给段寄存器?
movw $0x7c00, %ax
movw %ax, %ds
...
...
movw $0x6000, %ax
movw %ax, %ss
为什么不而不是直接置于段立即注册?
movw $0x7c00, %ds
...
movw $0x6000, %ss
我一直在关于编写程序集的几个例子,他们使用一个临时寄存器来传递一个段值寄存器的立即值。为什么需要在将立即数放入段寄存器之前将其寄存在某个寄存器中?
例子:
为什么使用临时寄存器将值传递给段寄存器?
movw $0x7c00, %ax
movw %ax, %ds
...
...
movw $0x6000, %ax
movw %ax, %ss
为什么不而不是直接置于段立即注册?
movw $0x7c00, %ds
...
movw $0x6000, %ss
因为英特尔没有为(mov seg, [ptr]
,等)提供的说明。所以你必须。事实证明很好,因为我们不再使用分段/选择器了。
但这并不是绝望。有与它加载段段一次lea
变种指令和偏移:
les di, [someptr]
(这实际上意味着:di = [someptr]; es = [someptr+2]
)
你也可以push
/pop
避免寄存器交换,在内存访问的代价当然延迟:
push immediate
pop es
许多寄存器只专注于一个目的,不能互换对于某些操作(bx
的偏移,计数为,结果为高位dx
,结果为ax
)。所以在机器代码文化中使用临时寄存器并交换它们并不奇怪。
这是这样,因为英特尔有获取或设置段寄存器的唯一指令是:
唯一posibility从寄存器或存储器访问复制,例如:
MOV DS, AX
# or
MOV DS, WORD PTR [EAX] # or any memory addressing like bellow
MOV DS, WORD PTR [EAX + EBX *2 + 0x456]
Intel Instruction Manuals。
关于装配说明的精简信息x86asm ref。
不允许立即移动到段寄存器。请参阅http://stackoverflow.com/questions/19074666/8086-why-cant-we-move-an-immediate-data-into-segment-register。 – lurker 2014-09-06 16:28:05
真正的答案是指令集空间很贵,因为只有很多位,而且每条指令都需要晶体管来支持它。因此,CPU设计者不能提供所有可能的有用指令。因此,他们针对常见的活动(通过提供“便利”指令)进行优化,并省略支持在代码量或频率方面很少发生的活动的说明。 “立即跳转到段”寄存器显然可以通过使用几条指令来完成,而且很少有必要,所以这已经足够了。你应该期待这一点。 – 2014-09-06 18:01:02