2015-04-23 152 views
0

是什麼在編碼的差異(ModRM:R/M,ModRM:REG)VS(ModRM:REG,ModRM:R/M)?具體說一下像CMPXCHG和DIVPD這樣的指令。我認爲寄存器和地址總是在第一個字節編碼,然後SIB和第二個字節的位移(如果需要的話)?這裏是我的代碼:的x64指令編碼(R/M,REG VS REG,R/M)

static void WriteRegisterToMemory(ICollection<Byte> bytes, IRegisterToMemoryInstruction instruction, Byte rex) 
    { 
     IAddress address = instruction.Address; 
     Byte register = instruction.Register; 

     if (address.NeedsRex) 
     { 
      rex |= 0x40; 
      if (address.RexB) 
       rex |= 1; 
      if (address.RexX) 
       rex |= 1 << 1; 
     } 

     if (register > 7) 
      rex |= 0x44;  // REX.R 
     if (rex != 0) 
      bytes.Add(rex); 

     bytes.AddRange(instruction.Opcode); 
     Byte modRM = (Byte)((register % 8) << 3); 
     modRM |= address.GetModRMAddressByte(); 
     bytes.Add(modRM); 
     address.WriteScaledIndexByteAndDisplacement(bytes); 
    } 

所以就像這兩個指令編碼完全相同,只是不同的操作碼? (添加到英特爾x64手冊第457頁)

Op/En Operand 1  Operand 2 
RM ModRM:reg (r, w) ModRM:r/m (r) 
MR ModRM:r/m (r, w) ModRM:reg (r) 

回答

1

w.r.t沒有任何區別。編碼,不同之處在於哪一個是源,哪一個是目的地。大多數指令有r/m源,除之類的東西cmpxchgbtsxaddxchg是含糊不清的(它的對稱),ALU OPS有一個r/m, r形式和r/m, imm形式,顯然MOV的內存。因此,在對這些指令進行編碼時(即使兩個操作數都是寄存器),請注意它們是「哪條路」,否則它們可能會以其操作數交換而結束。但是,就這些而言,最終在編碼方式上沒有什麼區別。

+0

編輯後問了另一個問題 –

+1

@RyanBrown好,我真的不明白,你想知道什麼,什麼是「編碼的相同」在這種情況下意味着精確?反正'之間的唯一區別添加[EAX],edx'和'添加EDX,[EAX]'(假設32位)爲操作碼,它們都具有的一個'字節ModRM 10' – harold

+0

我只是不明白,爲什麼他們有(reg然後r/m)和(r/m然後reg)。他們都編碼成一個字節(一般),因此他們並不是真正的兩個不同的操作數... –