Last but not least we're gonna give our app some functionality.  Without modifying the layout etc... we just going to make some adjustments in native-lib.cpp and test-nasm.asm.

A major caveat is that the we are programming a shared library to use with C++.  This means that strings defined in assembly language must be treated a bit more special than we should do in a (simple) assembly language program.  All addresses are position independent because a shared library can be loaded anywhere (not just anywhere there are rules for it) and that we don't know where in memory it will reside.  Knowing this we must inform the linker that almost everything is relocatable, thus strings too.  Many words for a complex matter, an example will tell us more.

modify native-lib.cpp like the example below:

#include <jni.h>
#include <string>

extern "C" char* GetGreeting(void);

extern "C"
JNIEXPORT jstring JNICALL Java_org_agguro_testnasm_MainActivity_stringFromJNI(
        JNIEnv *env,
        jobject /* this */)
    std::string hello = GetGreeting();
    return env->NewStringUTF(hello.c_str());

It's a plain C++ program right from the Android Studio wizard.  The only modification is the extern declaration of GetGreeting which takes no arguments and gets a pointer to a string from our assembly routine (linked with the file, and the calling of our function and pass the pointer to the string in the hello string.

we already created the file test-nasm.asm, so open it and put following code in it, don't be too scared (especially beginners can be) of the complexity, it's not just a "get the address of the string and return it in rax program, it's somewhat more complex).

; name: test-nasm.asm
; description: pass a pointer to "Hello from NASM" to the calling C++ program
; use: extern "C" char* GetMessage(void);

bits 64


global  GetGreeting
global  greeting:data               ; define global to make relocatable

section .data
    ; define our string here
    greeting:   db  "Hello from NASM", 0
    ; for c++ strings end with zero so our length isn't necessary, you can however define
    ; the length as global data so we can ask the length instead of calculating it

section .text

        push      rbp
        mov       rbp,rsp
        push      rbx
        call      .get_GOT
        pop       rbx
        add       rbx,_GLOBAL_OFFSET_TABLE_+$$-.get_GOT wrt ..gotpc
        mov 	  rax, qword [rbx + greeting wrt]
        mov       rbx,[rbp-8]
        mov       rsp,rbp
        pop       rbp

 Save it all and build your project.  Once build with no errors (if not, check all again) you will have this output in your emulator.