在我的 16 位程序中,GAS 对指令犹豫不决:
movw %ip, %dx
我觉得这很奇怪,因为移动段寄存器可以正常工作,例如:
movw %ss, %ax
完整的错误信息是:
错误:错误的寄存器名称 `%ip'
我的版本字符串是:
GNU 汇编器 (GNU Binutils) 2.22
在我的 16 位程序中,GAS 对指令犹豫不决:
movw %ip, %dx
我觉得这很奇怪,因为移动段寄存器可以正常工作,例如:
movw %ss, %ax
完整的错误信息是:
错误:错误的寄存器名称 `%ip'
我的版本字符串是:
GNU 汇编器 (GNU Binutils) 2.22
不幸的是,并非每个寄存器都可以轻松访问。有一些限制。
如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确实是违法的。
这里有一些使用call
thenpop %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 读数