Портирование встроенного GASM на x64 MASM Access Violing Проблема

В настоящее время я портирую некоторый код на MS Windows x64 с https://github.com/mono проект, который был написан для GCC Linux, и у меня возникли некоторые проблемы.

В настоящее время я не уверен, если мой перевод от x64 AT&Встроенный ASM в x64 MASM является правильным. Компилируется нормально, но мой тестовый пример не проходит как memcpy генерирует исключения / нарушения доступа к памяти после выполнения моей функции ASM. Мой перевод правильный?

Одна из вещей, с которой я действительно столкнулся, заключалась в том, что rip не доступен в Windows x64 MASM? Я действительно не знаю, как перевести эти оставшиеся строки AT&Синтаксис T (см. Ниже). Но я дал ему самую лучшую попытку. Я справился с отсутствием rip доступ правильно?

Если моя работа верна, то почему memcpy неудачу?

Вот связанный 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.

Вот текущая функция ASM.

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

Насколько я понимаю rcx регистр должен содержать указатель структуры и что я должен использовать rdx в pop,

Как я уже упоминал, у меня есть GCC ASM для платформ, отличных от Win64, который работает на этих платформах. Вот как выглядит этот код:

#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")

Спасибо за любую помощь, которую вы можете предложить! Я буду первым, кто признает, что моя сборка довольно ржавая.

4

Решение

Вы можете позволить gcc создать файл asm для вас (gcc также может создавать синтаксис MASM):

gcc -S -masm=intel myfile.c
0

Другие решения

Сравнивая две версии, мы видим некоторое расхождение:

movq $0x0, 0x00(%0)

Это не похоже rax сохраняется, но вместо этого слот памяти обнуляется.

leaq (%%rip), %%rdx

Вы должны быть в состоянии перевести это в Intel Synatx:

lea rdx, [rip]

что допустимо, если вы используете 64-битный режим относительной адресации.

И эта строка неправильно переведена с att:

call $ + 5
mov rdx, [rax+80h] ; looks reversed
pop rdx

Вот как я перевел оригинальный синтаксис газа выше:

mov qword ptr [rcx], 0
mov [rcx + 0x08], rbx
mov [rcx + 0x10], rax
mov [rcx + 0x18], rdx
mov [rcx + 0x20], rbp
mov [rcx + 0x28], rsp
mov [rcx + 0x30], rsi
mov [rcx + 0x38], rdi
mov [rcx + 0x40], r8
mov [rcx + 0x48], r9
mov [rcx + 0x50], r10
mov [rcx + 0x58], r11
mov [rcx + 0x60], r12
mov [rcx + 0x68], r13
mov [rcx + 0x70], r14
mov [rcx + 0x78], r15
lea rdx, [rip]
mov [rcx + 0x80], rdx
mov rdx, [rcx + 0x18]  ; restore old rdx since it's on clobber list

Обратите внимание, что я перешел rcx вокруг с rax просто чтобы сэкономить лишнее mov, Так rax спасается вместо rcx в синтаксисе газа. Возможно, вам придется изменить это в зависимости от ваших инвариантов.

Если он все еще не работает, я бы посоветовал пройти через него с помощью отладчика.

0

По вопросам рекламы [email protected]