简体   繁体   中英

Assembly code inlining in java and how to distinguish 32bit and 64bit os in java

I need to write some assembly injection in java code for tasks at my university. I have a class with native function

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);
}

Then I compiled the class using command javac -h AsmOR.java and I got header.

/* 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

I used assembly this assembly code, but I don't understand why are r8 and r9 parameters of the function. I tried to read javadoc, but it's useless.

global Java_org_user_AsmFun_AsmOR_or

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

Also, I wanted to use the coprocessor for double sum, but it doesn't work.

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

How to do this and how to distinguish between 32bit and 64bit version of the systems and load the dll library depending on the version?

Judging by the "mydll.dll" in your code, you are on Windows. That means the Microsoft x64 calling convention applies:

The first four arguments are placed onto the registers. That means RCX, RDX, R8, R9 for integer, struct or pointer arguments (in that order), and XMM0, XMM1, XMM2, XMM3 for floating point arguments. Additional arguments are pushed onto the stack (right to left). Integer return values (similar to x86) are returned in RAX if 64 bits or less. Floating point return values are returned in XMM0. Parameters less than 64 bits long are not zero extended; the high bits are not zeroed.

So RCX and RDX are the JNIEnv pointer and a pointer to your jclass , respectively.

As for your second question: fld dword [r8] will treat the contents of r8 as a float* and dereference that to get the actual float value. I think you have to use fild dword r8 if you want to load directly from a register.

The third question is already answered here .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM