Hey everyone. I've been working on this code for awhile and I'm wondering if there may be some more educated minds that can help me crack this final issue I am having.
I am currently porting some code from GCC Linux to Windows and I am having some challenges.
Currently I am unsure if my MASM is correct. It compiles fine but my test cases fail to work as memcpy throws exceptions/memory access violation errors after my ASM function executes.
One of the things I was really challenged by was the fact that rip is not accessible in x64 MASM? I really don't know how to translate that the remaining lines of the AT&T syntax (see below).
Compiler I am using is MS VS 2010.
Here is my related C++:
void mono_context_get_current(MonoContext cnt); //declare the ASM func
//Pass the static struct pointer to the ASM function mono_context_get_current
//The purpose here is to clobber it
#ifdef _MSC_VER
#define MONO_CONTEXT_GET_CURRENT(ctx) do { \
mono_context_get_current(ctx); \
} while (0)
#endif
static MonoContext cur_thread_ctx = {0};
MONO_CONTEXT_GET_CURRENT (cur_thread_ctx);
memcpy (&info->ctx, &cur_thread_ctx, sizeof (MonoContext)); //memcpy throws Exception. Memory Access Violation errors follow.
Here is my current ASM function.
mono_context_get_current PROTO
.code
mono_context_get_current PROC
mov rax, rcx ;Assume that rcx contains the pointer being passed
mov [rax+00h], rax
mov [rax+08h], rbx
mov [rax+10h], rcx
mov [rax+18h], rdx ;purpose is to offset from my understanding of the GCC assembly
mov [rax+20h], rbp
mov [rax+28h], rsp
mov [rax+30h], rsi
mov [rax+38h], rdi
mov [rax+40h], r8
mov [rax+48h], r9
mov [rax+50h], r10
mov [rax+58h], r11
mov [rax+60h], r12
mov [rax+68h], r13
mov [rax+70h], r14
mov [rax+78h], r15
call $ + 5
mov rdx, [rax+80h]
pop rdx
mono_context_get_current ENDP
END
To my understanding the rcx register should contain my struct pointer and that I should be using rdx for the above task.
As I mentioned I have GCC ASM for non-Win64 platforms which appears to work on those platforms. This is what that code looks like:
#define MONO_CONTEXT_GET_CURRENT(ctx) \
__asm__ __volatile__( \
"movq $0x0, 0x00(%0)\n" \
"movq %%rbx, 0x08(%0)\n" \
"movq %%rcx, 0x10(%0)\n" \
"movq %%rdx, 0x18(%0)\n" \
"movq %%rbp, 0x20(%0)\n" \
"movq %%rsp, 0x28(%0)\n" \
"movq %%rsi, 0x30(%0)\n" \
"movq %%rdi, 0x38(%0)\n" \
"movq %%r8, 0x40(%0)\n" \
"movq %%r9, 0x48(%0)\n" \
"movq %%r10, 0x50(%0)\n" \
"movq %%r11, 0x58(%0)\n" \
"movq %%r12, 0x60(%0)\n" \
"movq %%r13, 0x68(%0)\n" \
"movq %%r14, 0x70(%0)\n" \
"movq %%r15, 0x78(%0)\n" \
"leaq (%%rip), %%rdx\n" \
"movq %%rdx, 0x80(%0)\n" \
: \
: "a" (&(ctx)) \
: "rdx", "memory")
Thanks for any help you may be able to offer! I'll be the first to admit my assembly is pretty rusty.
Hi vamman,
first things first: Welcome to the forum.
The gcc inline assembler is a bit tricky. You've posted code with AT&T syntax; thats the point, because it's total different to the usual Intel syntax. So here is my advice:
- Isolate the inline code into a separate source module.
- Assuming your module is module.c. Compile it with the following command line: gcc -c module.c
- Use the tool objdump with the following command line: objdump -d -Mintel modul.o
And voila, you'll have Intel syntax. Good luck.
Gunther