我一直在尝试调用 JNIEnv 函数 GetVersion (对于初学者来说), 其索引为 4(根据 this site )。
我一直在使用this site供引用,并使用 [ebp + x] 而不是参数名称将 masm 代码调整为 nasm。
以下类和程序集文件应该创建一个乱码输出,但错误消息会将我引导到日志文件。
在这个非常大的日志文件中,我发现特别有趣的是,所谓的寄存器到内存映射似乎并不将寄存器的内容识别为 JNIEnv 函数(在 eax 中),而是将其识别为未知值。
谁能告诉我我做错了什么?
我只会根据请求附加日志,因为它相当大。
Java 代码:
public class Ver {
private static native int ver();
public static void main(String[] args) {
System.loadLibrary("my32");
System.out.println(ver());
}
}
ASM 代码:
;my32.asm
segment .text
;JNIEXPORT void JNICALL Java_Ver_ver
; (JNIEnv *, jclass);
global _Java_Ver_ver
_Java_Ver_ver:
push ebp
mov ebp, esp
push ebx
mov ebx, [ebp+8]
mov eax, [ebx]
mov ebx, eax
mov eax, 4
mov ecx, 4
mul ecx
add ebx, eax
mov eax, [ebx]
push dword [ebp+8]
call [eax]
pop ebx
pop ebp
ret 8
;assembled using nasm -fwin32 my32.asm
;linked using gcc -o my32.dll -shared my32.obj
;with mingw-gcc
希望这对于 SSCE 来说是一个有趣的问题
此致
嗯
最佳答案
看来您的间接寻址太多了:
mov ebx, [ebp+8] ; ebx = env
mov eax, [ebx] ; eax = *env
...
mov eax, [ebx] ; eax = (*env)->GetVersion
...
call [eax] ; call *((*env)->GetVersion)
所以call
应该是call eax
(不带括号)。
此外,您可以删除偏移 ebx
的方法,只需执行 mov eax, [ebx + 16]
即可。或者使用call [ebx + 16]
。
关于java - 从 nasm 创建的 dll 使用 JNIEnv,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23580204/