使用內聯彙編調用方法,以便正如我所說的,我想打電話給使用使用gcc內聯彙編的方法。所以,我搜索了x86如何工作,以及調用約定是什麼,然後我嘗試了一些簡單的調用,完美地工作。然後我試圖嵌入V8,這是我原來的目標,但它沒有工作這麼好...... 這裏是我的代碼:在GCC
v8::Handle<v8::Value> V8Method::staticInternalMethodCaller(const v8::Arguments& args, int argsize, void* object, void* method)
{
int i = 0;
char* native_args;
// Move the ESP to the end of the array (argsize is the array size in byte)
asm("subl %1, %%esp;"
"movl %%esp, %0;"
: "=r"(native_args)
: "r"(argsize));
// This for loop only converts V8 type to native type,
// and puts them in the array:
for (; i < args.Length(); ++i)
{
if (args[i]->IsInt32())
{
*(int*)(native_args) = args[i]->Int32Value();
native_args += sizeof(int);
}
else if (args[i]->IsNumber())
{
*(float*)(native_args) = (float)(args[i]->NumberValue());
native_args += sizeof(float);
}
}
// Then call the method:
asm("call *%1;" : : "c"(object), "r"(method));
return v8::Null();
}
,這裏是生成的彙編:
__ZN3srl8V8Method26staticInternalMethodCallerERKN2v89ArgumentsEiPvS5_:
LFB1178:
.cfi_startproc
.cfi_personality 0,___gxx_personality_v0
.cfi_lsda 0,LLSDA1178
pushl %ebp
.cfi_def_cfa_offset 8
.cfi_offset 5, -8
movl %esp, %ebp
.cfi_def_cfa_register 5
pushl %ebx
subl $68, %esp
.cfi_offset 3, -12
movl $0, -12(%ebp)
movl 12(%ebp), %eax
/APP
# 64 "method.cpp" 1
subl %eax, %esp; movl %esp, %ebx; addl $4, %esp
# 0 "" 2
/NO_APP
movl %ebx, -16(%ebp)
jmp L74
L77:
movl -12(%ebp), %eax
movl %eax, (%esp)
movl 8(%ebp), %ecx
LEHB25:
call __ZNK2v89ArgumentsixEi
LEHE25:
subl $4, %esp
movl %eax, -36(%ebp)
leal -36(%ebp), %eax
movl %eax, %ecx
call __ZNK2v86HandleINS_5ValueEEptEv
movl %eax, %ecx
LEHB26:
call __ZNK2v85Value7IsInt32Ev
LEHE26:
testb %al, %al
je L75
movl -12(%ebp), %eax
movl %eax, (%esp)
movl 8(%ebp), %ecx
LEHB27:
call __ZNK2v89ArgumentsixEi
LEHE27:
subl $4, %esp
movl %eax, -32(%ebp)
leal -32(%ebp), %eax
movl %eax, %ecx
call __ZNK2v86HandleINS_5ValueEEptEv
movl %eax, %ecx
LEHB28:
call __ZNK2v85Value10Int32ValueEv
LEHE28:
movl %eax, %edx
movl -16(%ebp), %eax
movl %edx, (%eax)
movl -16(%ebp), %eax
movl (%eax), %ebx
movl $LC4, 4(%esp)
movl $__ZSt4cout, (%esp)
LEHB29:
call __ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc
movl -16(%ebp), %edx
movl %edx, (%esp)
movl %eax, %ecx
call __ZNSolsEPKv
subl $4, %esp
movl $LC5, 4(%esp)
movl %eax, (%esp)
call __ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc
movl %ebx, (%esp)
movl %eax, %ecx
call __ZNSolsEi
subl $4, %esp
movl $__ZSt4endlIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_, (%esp)
movl %eax, %ecx
call __ZNSolsEPFRSoS_E
subl $4, %esp
addl $4, -16(%ebp)
jmp L76
L75:
movl -12(%ebp), %eax
movl %eax, (%esp)
movl 8(%ebp), %ecx
call __ZNK2v89ArgumentsixEi
LEHE29:
subl $4, %esp
movl %eax, -28(%ebp)
leal -28(%ebp), %eax
movl %eax, %ecx
call __ZNK2v86HandleINS_5ValueEEptEv
movl %eax, %ecx
LEHB30:
call __ZNK2v85Value8IsNumberEv
LEHE30:
testb %al, %al
je L76
movl -12(%ebp), %eax
movl %eax, (%esp)
movl 8(%ebp), %ecx
LEHB31:
call __ZNK2v89ArgumentsixEi
LEHE31:
subl $4, %esp
movl %eax, -24(%ebp)
leal -24(%ebp), %eax
movl %eax, %ecx
call __ZNK2v86HandleINS_5ValueEEptEv
movl %eax, %ecx
LEHB32:
call __ZNK2v85Value11NumberValueEv
LEHE32:
fstps -44(%ebp)
flds -44(%ebp)
movl -16(%ebp), %eax
fstps (%eax)
movl -16(%ebp), %eax
movl (%eax), %ebx
movl $LC4, 4(%esp)
movl $__ZSt4cout, (%esp)
LEHB33:
call __ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc
movl -16(%ebp), %edx
movl %edx, (%esp)
movl %eax, %ecx
call __ZNSolsEPKv
subl $4, %esp
movl $LC5, 4(%esp)
movl %eax, (%esp)
call __ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc
movl %ebx, (%esp)
movl %eax, %ecx
call __ZNSolsEf
subl $4, %esp
movl $__ZSt4endlIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_, (%esp)
movl %eax, %ecx
call __ZNSolsEPFRSoS_E
subl $4, %esp
addl $4, -16(%ebp)
L76:
incl -12(%ebp)
L74:
movl 8(%ebp), %ecx
call __ZNK2v89Arguments6LengthEv
cmpl -12(%ebp), %eax
setg %al
testb %al, %al
jne L77
movl 16(%ebp), %eax
movl 20(%ebp), %edx
movl %eax, %ecx
/APP
# 69 "method.cpp" 1
call *%edx;
# 0 "" 2
/NO_APP
call __ZN2v84NullEv
leal -20(%ebp), %edx
movl %eax, (%esp)
movl %edx, %ecx
call __ZN2v86HandleINS_5ValueEEC1INS_9PrimitiveEEENS0_IT_EE
subl $4, %esp
movl -20(%ebp), %eax
jmp L87
L83:
movl %eax, (%esp)
call __Unwind_Resume
L84:
movl %eax, (%esp)
call __Unwind_Resume
L85:
movl %eax, (%esp)
call __Unwind_Resume
L86:
movl %eax, (%esp)
call __Unwind_Resume
LEHE33:
L87:
movl -4(%ebp), %ebx
leave
.cfi_restore 5
.cfi_restore 3
.cfi_def_cfa 4, 4
ret
.cfi_endproc
所以,這個靜態方法是一個回調(我之前做了一些簽名檢查),女巫應該調用提供有效C++本機參數的特定方法。爲了加快速度並避免args的副本,我試圖將所有參數加載到本地數組中,然後修改ESP以使此數組成爲參數。
方法調用的效果很好,但我沒有得到正確的參數......我已經做了很多關於函數調用的研究,調用約定,以及大量的試驗(這是所有成功的),但我不」不知道發生了什麼...有什麼我錯過了嗎?
基本上,被叫方應該在ESP中的頂部得到它的參數,在我的情況下,數組...(我精確的排列是有效的)
我用GCC。
不要爲是法國人還是不親遺憾,但請不要* *感到很抱歉對我們造成這個爛攤子!請格式化您的代碼,以便普通人可以閱讀它(這涉及新的行,空格,縮進,typedefs等)Merci! –