x86/x64 Add Displacement addressing

有些话、适合烂在心里 提交于 2019-12-22 04:37:31

问题


I'm writing a compiler for x86/x64 CPU instructions and I can't seem to figure out what people mean by 'displacement' address. For example the Add instruction is detailed here: http://www.c-jump.com/CIS77/CPU/x86/X77_0150_encoding_add_edx_displacement.htm

I'm just trying to implement the add instruction where a register is added to a normal memory address. The problem is, the address is a 'displacement address'. Does that mean the address is a signed value that's the offset from the instruction location?


回答1:


There are a few different forms of indirect operands in x86:

  1. [reg]
  2. [reg + displacement]
  3. [displacement]
  4. [reg * constant + reg]
  5. [reg * constant + reg + displacement]

The "displacement" is just a constant that gets added to the rest of the address. In cases where there is no component of the address other than the constant, it is still called a "displacement". This is mainly for consistency with the other addressing forms.

Another way to look at it is that all addresses are of the form

[reg * constant + reg + displacement]

With each of the components allowing a value of 0.

The [displacement] form is just the encoding where all components other than the displacement are zero.

As a compiler writer the last 2 forms are particularly interesting. They make it easy to encode things like pArray[index]->field + 1in a single instruction.




回答2:


That page is not accurate. The "add that takes a displacement" which it's talking about refers to the form add r[16|32], r/m[16|32] or add edx, [0xdisp] as you might see it in a disassembler's output. Assuming it's talking about the ADD instruction with opcode 0x03,

  • Encoding the edx register destination and specifying a 32-bit displacement as effective address in the ModR/M byte would give it the value of 0x15 (refer to the Intel® 64 and IA-32 Architectures Software Developer’s Manual Vol. 2, page 41, table 2-2).
  • The effect of this instruction is to add the dword at the memory address disp to the contents of edx.
  • The actual encoding of the instruction would thus be: \x03\x15\x00\x00\x00\x01, for a displacement of 1 byte.



回答3:


There is no "special add that takes a displacement", that page is being unnecessarily confusing - this is just part of the normal memory operand encoding.

add is a fairly standard instruction that is encoded the same way as all the alu-ops are: there is a special case for using al as destination and an immediate as the source (04 ib), using ax/eax/rax as the destination and an immediate as the source (+ 05 imm), three versions of add r/m, imm (one for 8bit destinations, one for wider destinations and a sign-extended 8bit source, one for wider destinations and a wide source), and of course an add r, r/m and add r/m, r.

This is just a special case of add r, r/m, where the r/m takes the form of a displacement: see note #1 of ModRM encoding.

So they just mean add edx, [sdword]. (but they misencoded the reg field, edx corresponds to 010, not 011)



来源:https://stackoverflow.com/questions/13329611/x86-x64-add-displacement-addressing

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!