为什么使用临时寄存器将值传递给段寄存器?

时间:2014-09-06 16:24:20

标签: assembly x86 gas

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

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

为什么不将直接放在段寄存器中呢?

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

2 个答案:

答案 0 :(得分:5)

因为英特尔没有提供相关说明(mov seg, [ptr]mov seg, imm16等)。所以你必须这样做。结果很好,因为我们不再使用分段/选择器了。

但它并非没有希望。有lea变量指令和段一次加载段和偏移量:

les di, [someptr]

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

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

push immediate
pop  es

许多寄存器仅专注于某个目的,并且不能与某些操作互换(bx表示偏移,cx表示计数,dx表示更高阶的结果,{{1}为了结果)。因此,在机器代码文化中使用临时寄存器并交换它们并不奇怪。

答案 1 :(得分:1)

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

  • 获取注册 - > 操作码: 8C / r intruction: MOV r / m16,Sreg 说明: 将段寄存器移至r / m16。
  • 设置注册 - > 操作码: 8E / r 说明: MOV Sreg,r / m16 说明: 将r / m16移至段寄存器。

唯一的可能性是从寄存器或内存访问中复制,例如:

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