函数传参

基础类型

值传递

func f(a: Int) {

}

let a = 0
f(a: a)
#![allow(unused)]
fn main() {
fn f(a: i32) {

}

let a = 0;
f(a);
}
void f(int a) {

}

int a = 0;
f(a);
// arm64, AT&T

_main:
    sub sp, sp, #64
    stp x29, x30, [sp, #48]
    add x29, sp, #48


    // int a = 0;
    mov w8, #0
    str w8, [x29, #-4]

    // f(a);
    ldr x0, [x29, #-4]
    bl _f


    ldp x29, x30, [sp, #48]
    add sp, sp, #64

    ret

_f:
    sub sp, sp, #64
    stp x29, x30, [sp, #48]
    add x29, sp, #48


    ldp x29, x30, [sp, #48]
    add sp, sp, #64

    ret

地址/引用传递

func f(a: inout Int) {
    a += 1
}

var a = 0
f(a: &a)
#![allow(unused)]
fn main() {
fn f(a: &mut i32) {
    *a += 1;
}

let mut a = 0;
f(&mut a);
println!("{}", a);
}
void f(int *a) {
    *a += 1;
}

int a = 0;
f(&a);
// arm64, AT&T

_main:
    sub sp, sp, #64
    stp x29, x30, [sp, #48]
    add x29, sp, #48


    // int a = 0;
    mov w8, #0
    str w8, [x29, #-4]

    // f(&a);
    sub x0, x29, #4
    bl _f


    ldp x29, x30, [sp, #48]
    add sp, sp, #64

    ret

_f:
    sub sp, sp, #64
    stp x29, x30, [sp, #48]
    add x29, sp, #48


    // *a += 1;
    ldr w8, [x0]
    add w8, w8, #1
    str w8, [x0]


    ldp x29, x30, [sp, #48]
    add sp, sp, #64

    ret

栈上复合类型

值传递

栈上复合类型值传递的时候把值完全复制了一份,以保证被调用的函数不会修改函数外部的值

struct S {
    let a: Int
    let b: Int
    let c: Int
}

func f(s: S) {

}

let s = S(a: 0, b: 0, c: 0)
f(s: s)
#![allow(unused)]
fn main() {
#[derive(Clone)]
struct S {
    a: i32,
    b: i32,
    c: i32,
}

fn f(s: S) {

}

let s = S { a: 0, b: 0, c: 0 };
f(s.clone());
}
struct S {
    int a;
    int b;
    int c;
};

void f(struct S s) {

}

struct S s = {0, 0, 0};
f(s);
// arm64, AT&T

_main:
    sub sp, sp, #64
    stp x29, x30, [sp, #48]
    add x29, sp, #48


    // struct S s = {0, 0, 0};
    mov w8, #0
    str w8, [x29, #-4*3]
    mov w8, #0
    str w8, [x29, #-4*2]
    mov w8, #0
    str w8, [x29, #-4*1]

    // f(s);
    ldr w8, [x29, #-4*3]
    str w8, [x29, #-4*6]
    ldr w8, [x29, #-4*2]
    str w8, [x29, #-4*5]
    ldr w8, [x29, #-4*1]
    str w8, [x29, #-4*4]

    sub x0, x29, #4*6
    bl _f


    ldp x29, x30, [sp, #48]
    add sp, sp, #64

    ret

_f:
    sub sp, sp, #64
    stp x29, x30, [sp, #48]
    add x29, sp, #48


    ldp x29, x30, [sp, #48]
    add sp, sp, #64

    ret

地址/引用传递

栈上复合类型地址/引用传递的时候,被调用函数和外部共享同一份栈上内存,因此函数内部更改也会更改外部

struct S {
    let a: Int
    let b: Int
    let c: Int
}

func f(s: inout S) {
    s = S(a: 1, b: 1, c: 1)
}

var s = S(a: 0, b: 0, c: 0)
f(s: &s)
#![allow(unused)]
fn main() {
struct S {
    a: i32,
    b: i32,
    c: i32,
}

fn f(s: &mut S) {
    *s = S { a: 1, b: 1, c: 1 };
}

let mut s = S { a: 0, b: 0, c: 0 };
f(&mut s);
}
struct S {
    int a;
    int b;
    int c;
};

void f(struct S *s) {
    s->a = 1;
    s->b = 1;
    s->c = 1;
}

struct S s = {0, 0, 0};
f(&s);
// arm64, AT&T

_main:
    sub sp, sp, #64
    stp x29, x30, [sp, #48]
    add x29, sp, #48


    // struct S s = {0, 0, 0};
    mov w8, #0
    str w8, [x29, #-4*3]
    mov w8, #0
    str w8, [x29, #-4*2]
    mov w8, #0
    str w8, [x29, #-4*1]

    // f(&s);
    sub x0, x29, #4*3
    bl _f


    ldp x29, x30, [sp, #48]
    add sp, sp, #64

    ret

_f:
    sub sp, sp, #64
    stp x29, x30, [sp, #48]
    add x29, sp, #48


    // s->a = 1;
    mov w8, #1
    str w8, [x0]
    // s->b = 1;
    mov w8, #1
    str w8, [x0, #4]
    // s->c = 1;
    mov w8, #1
    str w8, [x0, #4*2]


    ldp x29, x30, [sp, #48]
    add sp, sp, #64

    ret

堆上复合类型

堆上复合类型把保存在栈上的堆内存地址传给了被调用的函数,因此被调用函数可以根据堆内存地址找到堆内存以修改堆内存数据

地址/引用传递

class C {
    var a: Int

    init(a: Int) {
        self.a = a
    }
}

func f(c: C) {
    c.a += 1
}

let c = C(a: 0)
f(c: c)
#![allow(unused)]
fn main() {
struct C {
    a: i32,
}

fn f(c: &mut Box<C>) {
    c.a += 1;
}

let mut c = Box::new(C { a: 0 });
f(&mut c);
}
struct C {
    int a;
};

void f(struct C *c) {
    c->a += 1;
}

struct C *c = malloc(sizeof(struct C));
c->a = 0;
f(c);
// arm64, AT&T

_main:
    sub sp, sp, #64
    stp x29, x30, [sp, #48]
    add x29, sp, #48


    // struct C *c = malloc(sizeof(struct C));
    mov	x0, #4
    bl _malloc
    str x0, [x29, #-8]

    // c->a = 0;
    mov w8, #0
    ldr x9, [x29, #-8]
    str w8, [x9]

    // f(c);
    ldr x0, [x29, #-8]
    bl _f


    ldp x29, x30, [sp, #48]
    add sp, sp, #64

    ret

_f:
    sub sp, sp, #64
    stp x29, x30, [sp, #48]
    add x29, sp, #48


    // c->a += 1;
    ldr w8, [x0]
    add w8, w8, #1
    str w8, [x0]


    ldp x29, x30, [sp, #48]
    add sp, sp, #64

    ret