0
\$\begingroup\$

I'm writing a brainfuck compiler in rust, that takes brainfuck instructions and converts them to a very basic assembly form, and then compiles that into binary, if you are not familiar with brainfuck I have included some resources, but the basic premise is this, the language operates with a memory tape, and there are 8 commands, the functions below correspond very crudely to the assembly for each command. If someone could verify that my Assembly associations are correct I would appreciate that greatly as I am not very comfortable in assembly.

My Projects Repo

Brainf*ck wikipedia

I could really use help perfecting the whole project, but this is just about the assembly.

use std::process::Command;

pub trait InstructionSet {
    const ENTRY_POINT: &'static str;
    const FILE_EX: &'static str;
    fn compile_to_bin_cmd(filename: &str) -> Vec<Command>;
    fn initialize_header() -> String;
    fn generate_inc_ptr() -> String;
    fn generate_dec_ptr() -> String;
    fn generate_inc_val() -> String;
    fn generate_dec_val() -> String;
    fn generate_lp_start(loop_label: &str) -> String;
    fn generate_lp_end(loop_label: String) -> String;
    fn generate_read() -> String;
    fn generate_write() -> String;
    fn initialize_footer() -> String;
}

pub(crate) struct M1;
impl InstructionSet for M1 {
    const ENTRY_POINT: &'static str = "_main";
    const FILE_EX: &'static str = ".s";

    fn compile_to_bin_cmd(filename: &str) -> Vec<Command> {
        let mut cmd = Command::new("gcc");
        cmd.args(["-o", &filename, &(filename.to_owned() + Self::FILE_EX)]);
        vec![cmd]
    }

    fn initialize_header() -> String {
        format!(
            "
.data
    .p2align 2
    MEM:
        .zero 4096

.section    __TEXT,__text,regular,pure_instructions
.build_version macos, 13, 0
.global {0}                           ; -- Begin function main

.p2align 2
{0}:
    ; init mem ptr
    adrp    x10, MEM@PAGE
    add     x10, x10, MEM@PAGEOFF

    ; value register
    mov     w12, #0

        ",
            Self::ENTRY_POINT
        )
    }

    fn generate_inc_ptr() -> String {
        "
    strb     w12, [x10]     ; inc ptr
    add      x10, x10, #1
    ldrb     w12, [x10]
        "
        .to_string()
    }

    fn generate_dec_ptr() -> String {
        "
    strb    w12, [x10]
    sub     x10, x10, #1
    ldrb    w12, [x10]
        "
        .to_string()
    }

    fn generate_inc_val() -> String {
        "
    ldrb    w12, [x10]
    add     w12, w12, #1
    strb    w12, [x10]
        "
        .to_string()
    }

    fn generate_dec_val() -> String {
        "
    ldrb    w12, [x10]
    sub     w12, w12, #1
    strb    w12, [x10]
        "
        .to_string()
    }

    fn generate_lp_start(loop_label: &str) -> String {
        format!(
            "
.p2align 2
loop_{}: // loop start
            ",
            loop_label
        )
    }

    fn generate_lp_end(loop_label: String) -> String {
        format!(
            "
    ldrb    w12, [x10]
    cbz     w12, loop_{} // loop end
            ",
            loop_label
        )
    }

    fn generate_read() -> String {
        "
    mov     x1, x10  ; read byte from stdin
    mov     x0, #1
    mov     x2, #1
    mov     x16, #3
    svc     0
        "
        .to_string()
    }

    fn generate_write() -> String {
        "
    mov     x0, #1  ; write byte to stdout
    mov     x1, x10
    mov     x2, #1
    mov     x16, #4
    svc     0
        "
        .to_string()
    }

    fn initialize_footer() -> String {
        "
.p2align 2
end:               ; exit with status 0
    mov     x0, #0
    mov     x16, #1
    svc     0
    "
        .to_string()
    }
}

\$\endgroup\$
1

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Browse other questions tagged or ask your own question.