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 呼び出し規約が適用されます。

最初の 4 つの引数がレジスタに配置されます。つまり、RCX、RDX、R8、R9 が整数、構造体、またはポインター引数 (この順序で) に対応し、XMM0、XMM1、XMM2、XMM3 が浮動小数点引数に対応します。追加の引数はスタックに (右から左に) プッシュされます。整数の戻り値 (x86 と同様) は、64 ビット以下の場合、RAX で返されます。浮動小数点の戻り値は XMM0 に返されます。長さが 64 ビット未満のパラメーターはゼロ拡張されません。上位ビットはゼロになりません。

したがって、RCX と RDX は、それぞれ JNIEnv ポインターと へのポインターjclassです。

2 番目の質問についてfld dword [r8]は、の内容をr8として扱い、それfloat*を逆参照して実際の float 値を取得します。fild dword r8レジスタから直接ロードしたい場合は、使用する必要があると思います。

3 番目の質問は、すでにここで回答されています

于 2020-02-18T13:52:02.250 に答える