2010-10-13 194 views
1
_memcpy_r SEGMENT 

memcpy_r PROC 
mov r10, rdi 
mov r11, rsi 
mov rdi, rcx 
mov rsi, rdx 
mov rcx, r8 
shr rcx, 3 
rep movsq 
mov rcx, r8 
and rcx, 7 
rep movsb 
mov rsi, r11 
mov rdi, r10 
ret 
memcpy_r ENDP 

_memcpy_r ENDS 

END 

我有一個.asm文件,我在Visual Studio 2010項目中使用上述代碼。它設置爲使用Microsoft宏彙編程序(ml64.exe)進行編譯。 該程序在程序的第一行(mov r10,rdi)上發生訪問衝突異常時崩潰。有誰知道爲什麼嗎?此代碼爲什麼會導致訪問衝突異常?

編輯:我應該澄清。如果我刪除第一行,那麼異常仍然會發生在下一行。如果我刪除它,它發生在下一個(mov rdi,rcx)。

+0

'r10'寄存器是否存在於x86-64平臺上?我真的在問......從來沒有見過這樣的......你有沒有試過把'r10'的所有參考文件改爲'rax'? – jyz 2010-10-13 12:24:17

+0

我原本是推rdi,而我仍然有例外。 如果r10不存在,則不會編譯。 – Jarrod 2010-10-13 12:37:10

+0

正確:http://en.wikipedia.org/wiki/X86-64 – jyz 2010-10-13 12:45:36

回答

1

正如Zack建議的那樣,嘗試將您的過程放入包含代碼的段中。在MASM,你通常做這個喜歡這樣的:

.code 
memcpy_r PROC 
[ ... ] 
memcpy_r ENDP 

END 

[EDIT2]要與其他代碼鏈接,你可能還需要標記PROCPUBLIC。作爲一個側面說明,既然你沒有另外指定,MASM是一個Windows程序,我假設你正在裝配這個在Win64上使用?如果是這種情況,您似乎不會遵循Win64 calling convention,它會通過RCX,RDX,R8R9中的前4個參數。

+0

mov r10,rdi mov r11,rsi上面只是我使用寄存器而不是堆棧來保存rdi和rsi的值。我在下一行訪問我的參數,如你所見,使用rcx,rdx和r8。 .CODE做到了,謝謝! :) – Jarrod 2010-10-19 05:08:25

0

如果您將項目編譯爲i386可執行文件,那麼它將以傳統模式運行,無需訪問64位寄存器(%rax,%r10等)。也許這是問題?反彙編您的可執行文件並檢查編譯器生成的代碼 - i386或x86_64。

+0

不是這樣。該OP使用64位版本的MASM(ml64.exe),該版本生成64位可執行文件。 – PhiS 2010-10-14 16:55:59

1

我懷疑你的問題是你正在爲這段代碼定義你自己的特殊段,並且它沒有被標記爲可執行文件在um可執行文件中,所以它被加載到拒絕執行權限的內存區域。毫無疑問,有一些方法可以告訴MASM一段將包含代碼,而不是數據;嘗試一下。