GAS无法识别寄存器%ip

Haw*_*ken 1 assembly gnu-assembler att

在我的16位程序中,GAS拒绝执行以下指令:

movw %ip, %dx
Run Code Online (Sandbox Code Playgroud)

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

movw %ss, %ax
Run Code Online (Sandbox Code Playgroud)

完整的错误消息是:

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

我的版本字符串是:

GNU汇编器(GNU Binutils)2.22

osg*_*sgx 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确实是非法的。

这里有一些阅读ip call然后使用pop %ax序列的示例: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
Run Code Online (Sandbox Code Playgroud)

或控制寄存器的编写:

 MOV    r32 CRn 0F20   r ...    Move to Control Registers
Run Code Online (Sandbox Code Playgroud)

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

Update2:根据/sf/answers/73357791/,在x86_64中使用LEA读取EIP

  • “调用/弹出”序列的问题在于,您需要为此工作的堆栈,在操作系统启动期间可能并非如此。 (2认同)