0

我需要用 Java 代码为我大学的任务编写一些程序集注入。我有一个具有本机功能的课程

import java.io.File;

public class AsmOR {
    static {
        String path = System.getProperty("user.dir");

        System.load(path+File.separator+"mydll.dll");
    }

    public static native int or(int num1, int num2);
}

然后我使用命令 javac -h AsmOR.java 编译了这个类,我得到了标题。

/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class org_user_AsmFun_AsmOR */

#ifndef _Included_org_user_AsmFun_AsmOR
#define _Included_org_user_AsmFun_AsmOR
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     org_user_AsmFun_AsmOR
 * Method:    or
 * Signature: (II)I
 */
JNIEXPORT jint JNICALL Java_org_user_AsmFun_AsmOR_or
  (JNIEnv *, jclass, jint, jint);

#ifdef __cplusplus
}
#endif
#endif

我用汇编这个汇编代码,但我不明白为什么函数的参数是r8和r9。我试图阅读 javadoc,但它没用。

global Java_org_user_AsmFun_AsmOR_or

Java_org_user_AsmFun_AsmOR_or:
    mov rax,r8
    or rax,r9
    ret 32
end

另外,我想使用协处理器进行双倍求和,但它不起作用。

    fld dword [r8]
    fld dword [r9]
    fadd st0,st1
    fistp dword [rax]
    ret 32

如何做到这一点以及如何区分系统的32位和64位版本并根据版本加载dll库?

4

1 回答 1

0

从代码中的“mydll.dll”来看,您在 Windows 上。这意味着Microsoft x64 调用约定适用:

前四个参数放置在寄存器中。这意味着 RCX、RDX、R8、R9 用于整数、结构或指针参数(按此顺序),以及 XMM0、XMM1、XMM2、XMM3 用于浮点参数。附加参数被压入堆栈(从右到左)。如果 64 位或更少,则在 RAX 中返回整数返回值(类似于 x86)。浮点返回值在 XMM0 中返回。长度小于 64 位的参数不进行零扩展;高位不归零。

所以 RCX 和 RDX 分别是 JNIEnv 指针和指向 your 的指针jclass

至于你的第二个问题:fld dword [r8]将内容r8视为 afloat*并取消引用以获得实际的浮点值。fild dword r8如果您想直接从寄存器加载,我认为您必须使用。

第三个问题已经在这里回答了

于 2020-02-18T13:52:02.250 回答