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
不幸的是,并非每个寄存器都可以轻松访问。有一些限制。
如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