YASM assembly call stdout.write in jitted function

I'm trying to write a compiler right on time, and I have a piece of code that just doesn't want to work. My platform is x86-64 ubuntu.

I have the following code written in yasm:

bits 64

mov rdx, 1
mov rcx, 'A'
mov rbx, 1
mov rax, 4
int 0x80
ret

So, if I understand correctly, this should write Ato stdout. Now I will compile this code with

yasm -f bin test.yasm

As a result, the following machine code appeared:

0x48 0xc7 0xc2 0x01 0x00 0x00 0x00 0x48 0xc7 0xc1 0x41 0x00
0x00 0x00 0x48 0xc7 0xc3 0x01 0x00 0x00 0x00 0x48 0xc7 0xc0
0x04 0x00 0x00 0x00 0xcd 0x80 0xc3

and then I read the resulting C ++ code and call it:

void *memory = allocate_executable_memory(sizeof(code));
emit_code_into_memory(sizeof(code), code, memory);
JittedFunc func = reinterpret_cast<JittedFunc>(memory);
func();

I think the C ++ part is great, as I already tried it with simple arithmetic operations and worked well.

Thus, in any case, there is no segmentation error, the code seems to be executed, but nothing happens, there is nothing in stdout.

Any tips?

// EDIT: full C ++ code:

#include <stdio.h>
#include <string.h>
#include <sstream>
#include <iostream>
#include <iomanip>
#include <sys/mman.h>

void* allocate_executable_memory(size_t size) {
    void *ptr = mmap(
        0,
        size,
        PROT_READ | PROT_WRITE | PROT_EXEC,
        MAP_PRIVATE | MAP_ANONYMOUS,
        -1,
        0
    );
    if (ptr == (void*)(-1)) {
        perror("mmap");
        return nullptr;
    }
    return ptr;
};

void emit_code_into_memory(size_t code_length, uint8_t *code, void *memory) {
    memcpy(reinterpret_cast<uint8_t*>(memory), code, code_length);
};

typedef void (*JittedFunc)();

int main(int argc, char* argv[]) {
    /* Use like this:
    bin/jit 0xb8 0x11 0x00 0x00 0x00 0xc3
    */
    if (argc <= 1) {
        return 1;
    }

    uint8_t code[argc-1];
    for (int i = 1; i < argc; i++) {
        code[i-1] = std::stoul(argv[i], nullptr, 16);
    }

    void *memory = allocate_executable_memory(sizeof(code));
    emit_code_into_memory(sizeof(code), code, memory);
    JittedFunc func = reinterpret_cast<JittedFunc>(memory);
    func();
    return 0;
};
+4
1

Syscall , , . , 64 syscall . , 32 . , , stat, strace:

stat(NULL, NULL) = -1 EFAULT (Bad address)

:

push 'A'
mov rdi, 1   ; stdout
mov rsi, rsp ; buf
mov rdx, 1   ; count
mov rax, 1   ; sys_write
syscall
pop rdi      ; cleanup
ret

. add rsp, 8. eax.

32- :

push ebx     ; callee-saved
push 'A'
mov ebx, 1   ; stdout
mov ecx, esp ; buf
mov edx, 1   ; count
mov eax, 4   ; sys_write
int 0x80
pop edi      ; cleanup buf
pop ebx      ; restore ebx
ret

, ebx .

+4

Source: https://habr.com/ru/post/1621274/


All Articles