2015-08-09 132 views
1

衆所周知,當存儲器到存儲器的移動不可能時,MOV指令允許寄存器註冊移動。爲什麼是這樣?x86程序集MOV指令 - 寄存器到寄存器和存儲器到存儲器

我讀過here內存到內存的移動是不允許的,因爲它使CPU複雜化,並且RAM必須處於讀模式或寫模式,並且有任何給定的指令。有沒有人能夠在此擴大?爲什麼RAM必須處於讀取模式和寫入模式?在單個指令中,如何從寄存器中讀取和寫入數據,而不是從RAM中讀取數據?

+2

使用movs [b/w/d]指令可以將一個字節,一個字或一個雙字從一個存儲位置複製到另一個存儲位置。 http://x86.renejeschke.de/html/file_module_x86_id_203.html –

+0

這是合理的寫作,使事情變得複雜,因爲它應該是原子。搜索讀取 - 修改 - 寫入。 –

+8

在x86的情況下,實際的原因是指令編碼對於兩個內存(有效地址)操作數沒有空間。解決方法是某些指令具有隱式操作數,例如上面提到的'MOVS',甚至是'PUSH'/'POP',並且這些操作數可以執行內存到內存的拷貝。 – Jester

回答

2

因爲英特爾這樣設計的,並且具有編碼的靈活性or [di], [si]即使在使用or al, [si]時也會使指令更長。

你讀到關於讀或寫模式的內容沒有意義,因爲or [rdi], rax做了讀 - 修改 - 寫。所以總是有兩個指令,即使除了幾條可以讀取一個位置並寫入另一個位置的指令(見下文)之外。

當英特爾設計x86時,他們決定限制編碼爲的指令的複雜性,因爲每個指令只允許爲一個操作數選擇尋址模式。另一個寄存器操作數在也選擇尋址模式的字節中由3位選擇。 (或者3位作爲操作碼的一部分,或者3位填充到其他地方......當前的x86指令編碼有這麼多特殊情況......)

x86-64增加了一個額外的位來增加寄存器的數量,但沒有改變任何根本。 (雖然它確實添加了RIP相對尋址。)

請參閱https://stackoverflow.com/tags/x86/info的英特爾手冊鏈接。

大多數x86指令採取這些形式

op r, r/m32 
op r/m32, r 

在GP寄存器的r是一個一個,和R/M32是寄存器或存儲器的操作數,這取決於尋址模式。

這兩個版本通常是不同的操作碼,即使它們共享相同的助記符。因此,從硬件/機器語言POV中,內存源和內存目標版本是兩個單獨的指令。 mov本身有許多不同的操作碼,適用於各種特殊情況。 (特別是如果您計算移入/移出控制寄存器)。

正如人們在註釋中注意到的那樣,存在讀和寫存儲器的指令,其中至少一個操作數具有不在通常的mod/rm中編碼的隱式位置尋址模式編碼。

  • movs:string move。 (除rep之外不要使用,超慢)
  • push r/m32(例如push [rax])。