In my 16bit program GAS is balking at the instruction:

movw %ip, %dx

I find this strange as moving a segment register works fine, for example:

movw %ss, %ax

The full error message is:

Error: bad register name `%ip'

And my version string is:

GNU assembler (GNU Binutils) 2.22

有帮助吗?

解决方案

Unfortunately, not every register can be easily accessed. There are some limitations.

As listed in x86 wikibook, GPR section, in x86 there are 8 General-Purpose Registers (GPRs): AX, CX, DX, BX, SP, BP, SI, DI, which can be used in many commands. They are encoded as 3 bits; and there is no space in the instruction encoding to encode Special registers, like EIP (IP), or EFLAGS (FLAGS).

If you scroll wikibook down, there is a section about IP:

Instruction Pointer

The EIP register contains the address of the next instruction to be executed if no branching is done.

EIP can only be read through the stack after a call instruction.

So, it is really illegal to use mov to read IP.

There are some examples of reading ip with call then pop %ax sequence here: http://www.programmersheaven.com/mb/x86_asm/267963/267963/how-to-access-ip-register/

Update: About reading of SS register:

There are actually many variant of mov instruction encoding, e.g. in this table we see segment reading

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

or Control Register writing:

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

but there is still no MOV for IP register.

Update2: in x86_64 there is a reading of EIP with LEA, according to https://stackoverflow.com/a/1047968/196561

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top