2014-09-06 89 views
1

我一直在关于编写程序集的几个例子,他们使用一个临时寄存器来传递一个段值寄存器的立即值。为什么需要在将立即数放入段寄存器之前将其寄存在某个寄存器中?
例子:
为什么使用临时寄存器将值传递给段寄存器?

movw $0x7c00, %ax 
movw %ax, %ds 
... 
... 
movw $0x6000, %ax 
movw %ax, %ss 

为什么不而不是直接置于段立即注册?

movw $0x7c00, %ds 
... 
movw $0x6000, %ss 
+2

不允许立即移动到段寄存器。请参阅http://stackoverflow.com/questions/19074666/8086-why-cant-we-move-an-immediate-data-into-segment-register。 – lurker 2014-09-06 16:28:05

+0

真正的答案是指令集空间很贵,因为只有很多位,而且每条指令都需要晶体管来支持它。因此,CPU设计者不能提供所有可能的有用指令。因此,他们针对常见的活动(通过提供“便利”指令)进行优化,并省略支持在代码量或频率方面很少发生的活动的说明。 “立即跳转到段”寄存器显然可以通过使用几条指令来完成,而且很少有必要,所以这已经足够了。你应该期待这一点。 – 2014-09-06 18:01:02

回答

5

因为英特尔没有为(mov seg, [ptr],​​等)提供的说明。所以你必须。事实证明很好,因为我们不再使用分段/选择器了。

但这并不是绝望。有与它加载段段一次lea变种指令和偏移:

les di, [someptr] 

(这实际上意味着:di = [someptr]; es = [someptr+2]

你也可以push/pop避免寄存器交换,在内存访问的代价当然延迟:

push immediate 
pop es 

许多寄存器只专注于一个目的,不能互换对于某些操作(bx的偏移,计数为,结果为高位dx,结果为ax)。所以在机器代码文化中使用临时寄存器并交换它们并不奇怪。

0

这是这样,因为英特尔有获取或设置段寄存器的唯一指令是:

  • 获得注册 - >操作码:8C/R按照压:MOV R/m16,Sreg说明:将段寄存器移至r/m16。
  • 设置寄存器 - >操作码:8E/R指令:MOV SREG,R/M16描述:移动转/ M16至段寄存器。

唯一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