2009-08-19 23 views
16

我想assermbly學會(如此忍受我),我在這條線得到一個編譯錯誤:大會:兩個存儲器之間移動解決

mov byte [t_last], [t_cur] 

的錯誤是

error: invalid combination of opcode and operands 

我懷疑這個錯誤的原因很簡單,就是它不可能讓mov指令在兩個內存地址之間移動,但是半小時的谷歌搜索,我還沒有能夠證實這一點 - 是這種情況嗎?

此外,假設我右這意味着我需要使用的寄存器作爲中間點用於複製存儲器:

mov cl, [t_cur] 
mov [t_last], cl 

請告訴我推薦寄存器使用(或應該使用堆棧,而不是)?

+3

有時更好轉到*源*而不是谷歌搜索,例如這裏是英特爾64&IA-32指令AM,在這裏你可以看到'mov'的操作數組合,http://www.intel.com/Assets/PDF/manual/253666.pdf – 2009-08-19 11:11:00

+0

規則的例外是指令不能帶兩個內存操作數;見[這裏](http://stackoverflow.com/questions/14510280/why-cant-mov-have-both-operands-as-memory-locations?lq=1#comment20229305_14510280)。 – legends2k 2015-06-13 11:05:17

回答

21

您的懷疑是正確的,您不能從內存移動到內存。

任何通用寄存器都可以。如果您不確定其中的內容並在完成後將其恢復,請記住按下PUSH寄存器。

+0

使用寄存器將數據本身推入堆棧有什麼好處嗎? – Justin 2009-08-19 11:02:28

+2

推入並隨後從堆棧彈出會添加兩個額外的內存訪問。 – hirschhornsalz 2009-08-19 12:49:50

3

還有從內存中移動數據到內存MOVS命令:

MOV SI, OFFSET variable1 
MOV DI, OFFSET variable2 
MOVS 
+0

可以工作,但需要格外小心:您需要保存si和di寄存器。我想這不值得複製一個字節。 – sharptooth 2009-08-19 11:03:56

+5

x86上的字符串命令可被視爲已過時。切勿使用它們。它們永遠不會比手工複製更快,但在大多數情況下要慢得多。 – hirschhornsalz 2009-08-19 12:51:52

+0

@hirschhornsalz,對不起,對不起,但你有任何關於字符串命令基本過時的詳細信息? – 2015-03-29 09:18:30

4

它在16位非常簡單,只要做到以下幾點:

 push  di 
    push  si 
    push  cx 
    mov  cx,(number of bytes to move) 
    lea  di,(destination address) 
    lea  si,(source address) 
    rep  movsb 
    pop  cx 
    pop  si 
    pop  di 

注:推動&持久性有機污染物neceessary如果你需要保存寄存器的內容。

+0

+1,因爲在某些情況下,最好了解工具箱中的所有工具。rep movsb/movsw是1個字節的操作碼,IIRC – 2012-10-11 11:43:26

+0

根據體系結構的不同,您可以使用pusha而不是單獨推送所有寄存器,而使用popa而不是全部彈出。 – BalinKingOfMoria 2015-06-02 03:39:47

+0

這工作在32位和64位,除了它使用該位系統的寄存器 – Rahly 2016-08-23 03:41:47

-2

只想和你討論「記憶障礙」。 C代碼

a = b; 

將被組裝到

mov %eax, a # suppose %eax is used as the temp 
mov b, %eax 

該系統不能保證分配的原子性。這就是爲什麼我們需要人民幣 (閱讀障礙)

+0

x86不能自動從內存複製到內存。障礙不會產生原子性,它們只會停止重新排序(編譯時間或運行時間或兩者,取決於障礙)。 – 2017-11-14 21:57:44

相關問題