I've written an x86 implementation of the Collatz Conjecture that takes an int and an amount of runs and then reduces the int to one using the Collatz conjecture and returns the number of iterations it took to do so, but I'm receiving a weird segmentation fault with no clear source when I try and run it using my cpp testing file
My x86 code is
global threexplusone
section .text
threexplusone:
    push rbp        ; load arg register
    mov rbp, rsp        ; move stack pointer to arg
    mov rax, [rbp+8]    ; input arg to rax
    mov rcx, rax        ; save arg in rcx
    cmp rax, 1      ; x == 1 ? Base Case
    je baseCase     
    xor rdx, rdx
    mov rbx, 2
    idiv rbx
    cmp rdx, 0      ; rax % 2 == 0 ? recurse : odd
    je recurse
    jmp odd
odd:
    mov rax, rcx        ; restores arg
    lea rax, [3*rax+1]  ; collatz math
    jmp recurse
recurse:
    push rax
    call threexplusone
    add rax, 1      ; numRuns++
    jmp end
baseCase:
    mov rax, 0      ; save rax to prevent segfault
end:
    mov rsp, rbp
    pop rbp
    ret
and my cpp testing is:
#include <iostream>
#include "timer.h"
#include <cstdlib>
#include <string>
using namespace std;
extern "C" int threexplusone(int);
int main() {
    int x, n, firstRun;
    timer t1;
    cout<<"Enter the number to test collatify"<<endl;
    cin>>x;
    cout<<"Enter the number of runs"<<endl;
    cin>>n;
    t1.start();
    for(int i=0;i<n;i++) {
        threexplusone(x);
    }
    t1.stop();
    firstRun=threexplusone(x);
    double mean = (t1.getTime()*1000)/n;
    cout<<"Number of iterations: "<<firstRun<<endl;
    cout<<"Mean runtime: "<<mean<<"ms"<<endl;
    return 0;
}
I know for sure that the implementation of the timer works just fine, but I'm confused as to what could possibly be causing the segmentation fault here. I've tried some things, like xoring some of the variables before using them or using imul instead of lea, but nothing has changed the issue thusfar.
 
    