views:

71

answers:

3
_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

I have the above code in a .asm file which I'm using in a Visual Studio 2010 project. It's set to compile using the Microsoft Macro Assembler (ml64.exe). The program crashes with an access violation exception on the first line of the procedure (mov r10, rdi). Does anyone know why?

EDIT: I should clarify. If I remove the first line, the exception still occurs on the next. If I remove that, it occurs on the next (mov rdi, rcx).

A: 

If you compile your project as i386 executable, then it will run in Legacy mode without access to 64-bit registers (%rax, %r10, etc). Maybe this is the problem? Disassemble your executable file and inspect what code is generated by compilator -- i386 or x86_64.

Vladimir Kupcov
That's not it. The OP is using the 64-bit version of MASM (ml64.exe), which produces 64-bit executables.
PhiS
+1  A: 

I suspect your problem is that you're defining your own special segment for this code and it's not being marked executable in the, um, executable, so it's being loaded into a memory area for which execute permission is denied. There is undoubtedly some way to tell MASM that a segment will contain code, not data; try that.

Zack
A: 

As Zack suggests, try putting your procedure in a segment meant to contain code. In MASM, you'd usually do this like such:

.code
memcpy_r PROC
[ ... ]
memcpy_r ENDP

END

[Edit2] To link with other code, you might also want to mark the PROC as PUBLIC.

[Edit1] As a side note, since you did not specify otherwise and MASM is a Windows program, I assume you are assembling this for use on Win64? If that is the case, you do not seem to be following the Win64 calling convention, which passes the first 4 parameters in RCX, RDX, R8, and R9.

PhiS
mov r10, rdi mov r11, rsi The above is just me preserving rdi and rsi's values using registers instead of the stack. I access my parameters on the next lines which, as you can see, use rcx, rdx and r8. .CODE did it, thanks! :)
Jarrod