1

在我的 16 位程序中,GAS 对指令犹豫不决:

movw %ip, %dx

我觉得这很奇怪,因为移动段寄存器可以正常工作,例如:

movw %ss, %ax

完整的错误信息是:

错误:错误的寄存器名称 `%ip'

我的版本字符串是:

GNU 汇编器 (GNU Binutils) 2.22

4

1 回答 1

5

不幸的是,并非每个寄存器都可以轻松访问。有一些限制。

x86 wikibook GPR 部分中所列,在 x86 中有 8 个通用寄存器 (GPR):AX、CX、DX、BX、SP、BP、SI、DI,可用于许多命令。它们被编码为 3 位;并且指令编码中没有空间来编码特殊寄存器,如 EIP (IP) 或 EFLAGS (FLAGS)。

如果你向下滚动wikibook,有一个关于IP的部分:

指令指针

如果没有进行分支,EIP 寄存器包含要执行的下一条指令的地址。

EIP 只能在调用指令后通过堆栈读取。

所以,用mov读取IP确实是违法的。

这里有一些使用callthenpop %ax序列读取 ip 的示例:http: //www.programmersheaven.com/mb/x86_asm/267963/267963/how-to-access-ip-register/

更新:关于读取 SS 寄存器:

mov 指令编码实际上有很多变体,例如在这张表中,我们看到了段读取

 mnemonic   op1 op2 po     o    description, notes 
 MOV    Sreg    r/m16   8E     r        Move

或控制寄存器写入:

 MOV    r32 CRn 0F20   r ...    Move to Control Registers

但仍然没有用于 IP 寄存器的 MOV。

更新 2:根据https://stackoverflow.com/a/1047968/196561 ,在 x86_64 中有一个带有 LEA 的 EIP 读数

于 2012-10-11T00:05:13.517 回答