V目前的编译思路是:编译生成对应的C代码,然后调用C编译器来生成可执行文件

    V语言的开发重点在编译器前端,C就是编译器后端

    现在也生成了js代码,估计也会生成wasm代码

    或者考虑基于LLVM,生成LLVM IR

    或者直接生成机器码


    使用-o参数就可以

    把当前目录的main.v代码生成main.c代码:

    通过查看V代码生成的C代码,可以更容易理解V编译器是如何编译的

    v的基本类型通过C的类型别名typedef来实现

    1. typedef int64_t i64;
    2. typedef int16_t i16;
    3. typedef int8_t i8;
    4. typedef uint64_t u64;
    5. typedef uint32_t u32;
    6. typedef uint16_t u16;
    7. typedef uint8_t byte;
    8. typedef uint32_t rune;
    9. typedef float f32;
    10. typedef double f64;
    11. typedef unsigned char* &byte; //字节指针
    12. typedef int* intptr; //整型指针
    13. typedef void* voidptr; //通用指针
    14. typedef char* charptr; //C字符指针
    15. typedef struct array array;
    16. typedef struct map map;
    17. typedef array array_string;
    18. typedef array array_int;
    19. typedef array array_byte;
    20. typedef array array_f32;
    21. typedef array array_f64;
    22. typedef array array_u16;
    23. typedef array array_u32;
    24. typedef array array_u64;
    25. typedef map map_int;
    26. typedef map map_string;
    27. typedef byte array_fixed_byte_300 [300];
    28. typedef byte array_fixed_byte_400 [400];
    29. typedef uint8_t byte;
    30. ...
    31. #ifndef bool
    32. typedef int bool; //布尔类型在C里面通过int类型来实现,1字节
    33. typedef byte bool;
    34. #define true 1 //true是整数常量1
    35. #define false 0 //false是整数常量0
    36. #endif

    常量

    int类型常量,生成C的宏定义:

    1. //V代码
    2. const (
    3. i=1 //int类型的常量
    4. )
    5. //C代码
    6. #define _const_i 1 //整数类型的常量通过C宏定义

    其他类型常量,生成C的全局变量,常量的不可修改,由V编译器负责检查

    这样就很好理解,V语言中的常量可以是任何类型,跟变量一样,甚至可以是函数调用的结果

    1. //V代码
    2. const (
    3. a=i8(11)
    4. b=i16(12)
    5. c=i64(13)
    6. d=byte(14)
    7. e=u16(15)
    8. f=u32(16)
    9. g=u64(17)
    10. h=f32(1.1)
    11. i=f64(1.2)
    12. bb=true
    13. )
    14. //C代码
    15. i8 _const_a; // inited later
    16. i16 _const_b; // inited later
    17. i64 _const_c; // inited later
    18. byte _const_d; // inited later
    19. u16 _const_e; // inited later
    20. u32 _const_f; // inited later
    21. u64 _const_g; // inited later
    22. f32 _const_h; // inited later
    23. f64 _const_i; // inited later
    24. bool _const_bb; // inited later
    25. void _vinit() { //然后在_vinit函数进行初始化
    26. _const_a = ((i8)(11));
    27. _const_b = ((i16)(12));
    28. _const_c = ((i64)(13));
    29. _const_d = ((byte)(14));
    30. _const_e = ((u16)(15));
    31. _const_f = ((u32)(16));
    32. _const_g = ((u64)(17));
    33. _const_h = ((f32)(1.1));
    34. _const_i = ((f64)(1.2));
    35. _const_bb = true;
    36. }

    枚举

    1. //V代码
    2. pub enum Color {
    3. blue =1 //如果没有指定初始值,默认从0开始,然后往下递增1
    4. green
    5. white
    6. black
    7. }
    8. c := Color.blue
    9. //C代码
    10. typedef enum {
    11. Color_blue = 1 ,
    12. Color_green, // 1
    13. Color_white, // 2
    14. Color_black, // 3
    15. } Color;
    16. Color c = Color_blue;

    模块

    V的模块,在生成对应C代码后,只是对应元素名称的前缀,毕竟C语言中没有模块的概念

    常量,结构体,接口,类型等一级元素生成C代码后的名称规则是:”模块名__名称”,用双下划线区隔

    结构体的方法等二级元素生成C代码后的名称规则是:”模块名 _ 类名 方法名”,用单下划线区隔

    例模块中的Color结构体的str()方法生成C代码后的名称为:mymodule__Color_str()

    函数

    主模块中的主函数和函数,生成等价的C的函数

    1. //V代码
    2. module main
    3. fn main() {
    4. println('from main')
    5. add(1,3)
    6. }
    7. pub fn add(x,y int) int { //pub的模块访问控制由V编译器负责检查,C没有pub的对应
    8. if x>0 {
    9. return x+y
    10. } else {
    11. return x+y
    12. }
    13. }
    14. //C代码
    15. int add(int x, int y); //函数声明
    16. int main(int ___argc, char** ___argv) { //主函数生成主函数
    17. _vinit(); //先执行初始化函数
    18. println(tos3("from main"));
    19. add(1, 3);
    20. return 0;
    21. }
    22. int add(int x, int y) {
    23. if (x > 0) {
    24. return x + y;
    25. } else {
    26. return x + y;
    27. }
    28. }

    函数defer语句

    C没有defer语句,V编译的时候就是把函数中的defer语句去掉,然后按后进先出的顺序放在defer语句之后的所有return语句前以及函数末尾,有各自独立的代码块

    1. //V代码
    2. fn main(){
    3. defer {defer_fn1()}
    4. defer {defer_fn2()}
    5. println('main start')
    6. if 1<2 {
    7. return
    8. }
    9. if 1==1 {
    10. return
    11. }
    12. println('main end')
    13. }
    14. fn defer_fn1(){
    15. println('from defer_fn1')
    16. }
    17. fn defer_fn2(){
    18. println('from defer_fn2')
    19. }
    20. //C代码
    21. int main(int ___argc, char** ___argv) {
    22. _vinit();
    23. println(tos3("main start"));
    24. if (1 < 2) {
    25. // defer
    26. defer_fn1();//defer语句之后的所有return语句之前
    27. // defer
    28. defer_fn2();//defer语句之后的所有return语句之前
    29. return 0;
    30. }
    31. if (1 == 1) {
    32. // defer
    33. defer_fn1();//defer语句之后的所有return语句之前
    34. // defer
    35. defer_fn2();//defer语句之后的所有return语句之前
    36. return 0;
    37. }
    38. println(tos3("main end"));
    39. // defer
    40. defer_fn1();//函数末尾
    41. // defer
    42. defer_fn2();//函数末尾
    43. return 0;
    44. }
    45. void defer_fn1() {
    46. println(tos3("from defer_fn1"));
    47. }
    48. void defer_fn2() {
    49. println(tos3("from defer_fn2"));
    50. }

    函数不确定个数参数

    不确定参数就是根据返回值的类型和调用的最大参数数量,编译时动态生成一个结构体

    然后把最后一个参数变为这个结构体的指针类型

    不确定参数结构体,会重用,如果有别的函数也是返回了相同类型的不确定参数,会直接使用,同时修改args数组的长度为调用过参数的最大值

    1. //V代码
    2. fn my_fn(i int,s string, others ...string) {
    3. println(i)
    4. println(s)
    5. println(others[0])
    6. println(others[1])
    7. println(others[2])
    8. }
    9. fn main() {
    10. my_fn(1,'abc','de','fg','hi')
    11. }
    12. //C代码
    13. struct varg_string { //自动生成不确定参数结构体
    14. int len;
    15. string args[4];
    16. };
    17. void main__my_fn(int i, string s, varg_string *others) {
    18. printf("%d\n", i);
    19. println(s);
    20. println(others->args[0]);
    21. println(others->args[1]);
    22. println(others->args[2]);
    23. }
    24. void main__main() {
    25. main__my_fn(
    26. 1, tos3("abc"),
    27. &(varg_string){.len = 3, .args = {tos3("de"), tos3("fg"), tos3("hi")}});
    28. }

    函数多返回值

    C的函数返回值只有1个,V的函数多返回值,就是把多返回值的组合,编译时动态生成一个结构体,然后返回结构体

    1. //V代码
    2. fn foo() (int, int) { //多返回值
    3. return 2, 3
    4. }
    5. fn some_multiret_fn(a int, b int) (int, int) {
    6. return a+1, b+1 //可以返回表达式
    7. }
    8. fn main() {
    9. a, b := foo()
    10. println(a) // 2
    11. println(b) // 3
    12. }
    13. //C代码
    14. typedef struct _V_MulRet_int_V_int _V_MulRet_int_V_int;
    15. struct _V_MulRet_int_V_int { //生成的返回值组合的结构体,还可以给其他函数共用
    16. int var_0;
    17. int var_1;
    18. };
    19. _V_MulRet_int_V_int main__foo() {
    20. return (_V_MulRet_int_V_int){.var_0 = 2, .var_1 = 3};
    21. }
    22. _V_MulRet_int_V_int main__some_multiret_fn(int a, int b) {
    23. return (_V_MulRet_int_V_int){.var_0 = a + 1, .var_1 = b + 1};
    24. }
    25. void main__main() {
    26. _V_MulRet_int_V_int _V_mret_49_a_b = main__foo();
    27. int a = _V_mret_49_a_b.var_0;
    28. int b = _V_mret_49_a_b.var_1;
    29. /*opt*/ printf("%d\n", a);
    30. /*opt*/ printf("%d\n", b);

    数组

    V的数组是用struct来实现的,生成C代码也是struct

    1. //V代码
    2. fn main() {
    3. a:=[1,3,5]
    4. b:=['a','b','c']
    5. println(a)
    6. println(b)
    7. }
    8. //C代码
    9. //第一部分: 从内置的vlib/built/array.v生成
    10. struct array {
    11. void* data;
    12. int len;
    13. int cap;
    14. int element_size;
    15. };
    16. typedef struct array array;
    17. typedef array array_string;
    18. typedef array array_int;
    19. typedef array array_byte;
    20. typedef array array_f32;
    21. typedef array array_f64;
    22. typedef array array_u16;
    23. typedef array array_u32;
    24. typedef array array_u64;
    25. //第三部分:数组使用的代码,字面量方式创建
    26. array_int a=new_array_from_c_array(3, 3, sizeof(int), EMPTY_ARRAY_OF_ELEMS( int, 3 ) { 1 , 3 , 5 }) ;
    27. array_string b=new_array_from_c_array(3, 3, sizeof(string), EMPTY_ARRAY_OF_ELEMS( string, 3 ) { tos3("a") , tos3("b") , tos3("c") }) ;
    28. println (array_int_str( a ) ) ;
    29. println (array_string_str( b ) ) ;
    30. }

    字符串

    V的字符串是用struct来实现的,生成C代码也是struct

    1. //V代码
    2. //vlib/builtin/string.v
    3. pub struct string {
    4. // var:
    5. // hash_cache int
    6. pub:
    7. str &byte // points to a C style 0 terminated string of bytes.
    8. len int // the length of the .str field, excluding the ending 0 byte. It is always equal to strlen(.str).
    9. }
    10. //string的各种内置方法:
    11. ...
    12. //使用代码:
    13. fn main(){
    14. mystr:='abc'
    15. mystr2:="def"
    16. println(mystr)
    17. println(mystr2)
    18. }
    19. //C代码
    20. //第一部分:vlib/builtin/string.v生成:
    21. typedef struct string string;
    22. struct string {
    23. byte* str;
    24. int len;
    25. };
    26. //string的各种内置方法生成:
    27. string string_left (string s, int n);
    28. string string_right (string s, int n);
    29. string string_substr2 (string s, int start, int _end, bool end_max);
    30. string string_substr (string s, int start, int end);
    31. //第二部分,使用代码:
    32. void main__main () {
    33. string mystr= tos3("abc") ;
    34. string mystr2= tos3("def") ;
    35. println ( mystr ) ;
    36. println ( mystr2 ) ;
    37. }

    字典

    V的字典是用struct来实现的,生成C代码也是struct

    结构体

    1. //V代码
    2. pub struct Point {
    3. x int
    4. y int
    5. }
    6. pub fn (p Point) str() string {
    7. return 'x is ${p.x},y is:${p.y}'
    8. }
    9. fn main() {
    10. p := Point{
    11. x: 1
    12. y: 3
    13. }
    14. println(p)
    15. }
    16. //C代码
    17. struct Point {
    18. int x;
    19. int y;
    20. };
    21. string Point_str (Point p); //函数声明
    22. string Point_str (Point p) { //函数定义,默认第一个参数是自己
    23. return _STR("x is %d,y is:%d", p .x, p .y) ;
    24. }
    25. void main__main () {
    26. Point p= (Point) { .x = 1 , .y = 3 } ;
    27. println (Point_str( p ) ) ;
    28. }

    结构体方法

    生成对应的C函数,默认第一个参数是对应的结构体类型的指针

    生成的C函数的命名规则是:”结构体名_方法名”

    1. //V代码
    2. pub fn (mut a array) insert(i int, val voidptr) {
    3. if i < 0 || i > a.len {
    4. panic('array.insert: index out of range (i == $i, a.len == $a.len)')
    5. }
    6. a.ensure_cap(a.len + 1)
    7. size := a.element_size
    8. C.memmove(a.data + (i + 1) * size, a.data + i * size, (a.len - i) * size)
    9. C.memcpy(a.data + i * size, val, size)
    10. a.len++
    11. }
    12. //C代码
    13. void array_insert(array *a, int i, void *val) { //默认第一个参数是对应类型指针
    14. if (i < 0 || i > a->len) {
    15. v_panic(_STR("array.insert: index out of range (i == %d, a.len == %d)", i,
    16. a->len));
    17. };
    18. array_ensure_cap(a, a->len + 1);
    19. int size = a->element_size;
    20. memmove((byte *)a->data + (i + 1) * size, (byte *)a->data + i * size,
    21. (a->len - i) * size);
    22. memcpy((byte *)a->data + i * size, val, size);
    23. a->len++;
    24. }

    结构体访问控制

    访问控制在C代码中没有体现,全部在V编译器中控制

    1. //V代码
    2. struct Foo {
    3. a int //私有,不可变(默认).在模块内部可访问,不可修改;模块外不可访问,不可修改
    4. mut:
    5. b int // 私有,可变.在模块内部可访问,可修改,模块外部不可访问,不可修改
    6. c int // (相同访问控制的字段可以放在一起)
    7. pub:
    8. d int // 公共,不可变,只读.在模块内部和外部都可以访问,但是不可修改
    9. pub mut:
    10. e int //公共,模块内部可访问,可修改;模块外部可访问,但是不可修改
    11. __global:
    12. f int // 全局字段,模块内部和外部都可访问,可修改,这样等于破坏了封装性,不推荐使用
    13. }
    14. fn main() {
    15. f:=Foo{}
    16. println(f)
    17. }
    18. //C代码
    19. typedef struct Foo Foo;
    20. struct Foo {
    21. int a;
    22. int b;
    23. int c;
    24. int d;
    25. int e;
    26. int f;
    27. };
    28. string Foo_str();
    29. void main__main() {
    30. Foo f = (Foo){.a = 0, .b = 0, .c = 0, .d = 0, .e = 0, .f = 0};
    31. println(Foo_str(f));
    32. }
    33. string Foo_str(Foo a) {
    34. return _STR("{\n a: %d\n b: %d\n c: %d\n d: %d\n e: %d\n f: %d\n}", a.a,a.b, a.c, a.d, a.e, a.f);
    35. }

    流程控制语句

    if语句,生成C if语句

    1. //V代码
    2. fn main() {
    3. a := 10
    4. b := 20
    5. if a < b {
    6. println('$a < $b')
    7. }
    8. else if a > b {
    9. println('$a > $b')
    10. }
    11. else {
    12. println('$a == $b')
    13. }
    14. }
    15. //C代码
    16. void main__main () {
    17. int a= 10 ;
    18. int b= 20 ;
    19. if ( a < b ) {
    20. printf( "%d < %d\n", a, b ) ;
    21. }
    22. else if ( a > b ) {
    23. printf( "%d > %d\n", a, b ) ;
    24. }
    25. else {
    26. printf( "%d == %d\n", a, b ) ;
    27. }

    if表达式语句,生成C的三元运算符 ? :

    1. //V代码
    2. fn main() {
    3. num := 777
    4. s := if num % 2 == 0 {
    5. 'even'
    6. }
    7. else {
    8. 'odd'
    9. }
    10. println(s) // "odd"
    11. }
    12. //C代码
    13. void main__main() {
    14. int num = 777;
    15. string s = ((num % 2 == 0) ? (tos3("even")) : (tos3("odd")));
    16. println(s);
    17. }

    match语句

    1. //V代码
    2. fn main() {
    3. os:='macos'
    4. match os {
    5. 'windows' {
    6. println('windows')
    7. }
    8. 'linux' {
    9. println('linux')
    10. }
    11. 'macos' {
    12. println('macos')
    13. }
    14. else {
    15. println('unknow')
    16. }
    17. }
    18. }
    19. //C代码
    20. void main__main() {
    21. string os = tos3("macos");
    22. string tmp1 = os;
    23. if (string_eq(tmp1, tos3("windows"))) {
    24. println(tos3("windows"));
    25. } else if (string_eq(tmp1, tos3("linux"))) {
    26. println(tos3("linux"));
    27. } else if (string_eq(tmp1, tos3("macos"))) {
    28. println(tos3("macos"));
    29. } else // default:
    30. {
    31. println(tos3("unknow"));
    32. };
    33. }

    match表达式语句

    1. //V代码
    2. fn main() {
    3. os:='macos'
    4. price:=match os {
    5. 'windows' {
    6. 100
    7. }
    8. 'linux' {
    9. 120
    10. }
    11. 'macos' {
    12. 150
    13. }
    14. else {
    15. 0
    16. }
    17. }
    18. println(price) //输出150
    19. }
    20. //C代码
    21. //生成嵌套的三元表达式
    22. void main__main() {
    23. string os = tos3("macos");
    24. string tmp1 = os;
    25. int price = ((string_eq(tmp1, tos3("windows")))
    26. ? (100)
    27. : ((string_eq(tmp1, tos3("linux")))
    28. ? (120)
    29. : ((string_eq(tmp1, tos3("macos"))) ? (150) : (0))));
    30. /*opt*/ printf("%d\n", price);
    31. }

    for循环

    传统的:for i=0;i<100;i++ {}

    1. //V代码
    2. fn main() {
    3. for i := 0; i < 10; i++ {
    4. if i == 6 {
    5. continue
    6. }
    7. println(i)
    8. }
    9. }
    10. //C代码
    11. for (int i = 0; i < 10; i++) {
    12. if (i == 6) {
    13. continue;
    14. };
    15. /*opt*/ printf("%d\n", i);
    16. };
    17. }

    替代while:for i<100 {}

    1. //V代码
    2. fn main() {
    3. mut sum := 0
    4. mut i := 0
    5. for i <= 100 {
    6. sum += i
    7. i++
    8. }
    9. println(sum) // 输出"5050"
    10. }
    11. //C代码
    12. void main__main () {
    13. int sum= 0 ;
    14. int i= 0 ;
    15. while ( i <= 100 ) {
    16. sum += i ;
    17. i ++ ;
    18. }

    无限循环:for {}

    1. //V代码
    2. fn main() {
    3. mut num := 0
    4. for {
    5. num++
    6. if num >= 10 {
    7. break
    8. }
    9. }
    10. println(num) // "10"
    11. }
    12. //C代码
    13. void main__main() {
    14. int num = 0;
    15. while (1) {
    16. num++;
    17. if (num >= 10) {
    18. break;
    19. };
    20. };
    21. /*opt*/ printf("%d\n", num);
    22. }

    遍历:for i in xxx {}

    类型定义

    类型定义type生成C的类型别名typedef

    1. //V代码
    2. pub struct Point {
    3. x int
    4. y int
    5. }
    6. type myint=int
    7. type myPoint=Point
    8. //C代码
    9. struct Point {
    10. int x;
    11. int y;
    12. };
    13. typedef int myint;
    14. typedef Point myPoint;

    接口

    1. //V代码
    2. //C代码

    泛型

    1. //V代码
    2. //C代码

    错误处理

    1. //V代码
    2. //C代码

    联合类型

    1. //V代码
    2. struct User {
    3. name string
    4. age int
    5. }
    6. pub fn (m &User) str() string {
    7. return 'name:$m.name,age:$m.age'
    8. }
    9. type MySum= int|string|User //联合类型声明
    10. i:=123
    11. s:='abc'
    12. u:=User{name:'tom',age:33}
    13. mut res:=MySum{} //声明联合类型变量
    14. res=i
    15. res=s
    16. res=u
    17. pub fn add(ms MySum) {
    18. match ms {
    19. int {
    20. println('ms is int,value is $it.str()')
    21. }
    22. string {
    23. println('ms is string,value is $it')
    24. }
    25. User {
    26. println('ms is User,value is $it.str()')
    27. }
    28. else {
    29. println('unknown')
    30. }
    31. }
    32. }
    33. //C代码
    34. #define SumType_int 1 // DEF2
    35. #define SumType_string 2 // DEF2
    36. #define SumType_User 3 // DEF2
    37. typedef struct {
    38. void *obj; //存储变量指针
    39. int typ; //联合类型中对应的类型常量,就是上面的宏定义
    40. } MySum;
    41. //声明联合类型变量
    42. MySum res = (MySum){EMPTY_STRUCT_INITIALIZATION};
    43. //变量赋值
    44. res = /*SUM TYPE CAST2*/ (MySum){.obj = memdup(&(int[]){i}, sizeof(int)),
    45. .typ = SumType_int};
    46. res = /*SUM TYPE CAST2*/ (MySum){.obj = memdup(&(string[]){s}, sizeof(string)), .typ = SumType_string};
    47. res = /*SUM TYPE CAST2*/ (MySum){.obj = memdup(&(User[]{u},sizeof(User)),
    48. .typ = SumType_User};
    49. //match类型判断
    50. if (tmp3.typ == SumType_int) {
    51. int *it = (int *)tmp3.obj;
    52. printf("res is:%.*s\n", int_str(*it).len, int_str(*it).str);
    53. } else if (tmp3.typ == SumType_string) {
    54. string *it = (string *)tmp3.obj;
    55. printf("res is:%p\n", it);
    56. } else if (tmp3.typ == SumType_User) {
    57. User *it = (User *)tmp3.obj;
    58. printf("res is:%.*s\n", User_str(&/* ? */ *it).len,
    59. User_str(&/* ? */ *it).str);
    60. } else // default:
    61. {
    62. println(tos3("unknown"));
    63. };

    运算符重载

    1. //V代码
    2. //C代码

    条件编译

    生成等价的C宏定义

    1. //V代码
    2. fn main() {
    3. $if windows {
    4. println('windows')
    5. }
    6. $if linux {
    7. println('linux')
    8. }
    9. $if macos {
    10. println('mac')
    11. }
    12. }
    13. //C代码
    14. VV_LOCAL_SYMBOL void main__main() {
    15. #if defined(_WIN32)
    16. {
    17. }
    18. #endif
    19. #if defined(__linux__)
    20. {
    21. }
    22. #endif
    23. #if defined(__APPLE__)
    24. {
    25. println(tos_lit("mac"));
    26. }
    27. #endif
    28. }
    1. //V代码
    2. fn main() {
    3. mut x := 0
    4. $if x32 {
    5. println('system is 32 bit')
    6. x = 1
    7. }
    8. $if x64 {
    9. println('system is 64 bit')
    10. x = 2
    11. }
    12. }
    13. //C代码
    14. void main__main() {
    15. int x = 0;
    16. #ifdef TARGET_IS_32BIT
    17. println(tos3("system is 32 bit"));
    18. x = 1;
    19. #endif
    20. ;
    21. #ifdef TARGET_IS_64BIT
    22. println(tos3("system is 64 bit"));
    23. x = 2;
    24. #endif
    25. ;
    1. //V代码
    2. fn main() {
    3. mut x := 0
    4. $if little_endian {
    5. println('system is little endian')
    6. x = 1
    7. }
    8. $if big_endian {
    9. println('system is big endian')
    10. x = 2
    11. }
    12. }
    13. //C代码
    14. void main__main() {
    15. int x = 0;
    16. #ifdef TARGET_ORDER_IS_LITTLE
    17. println(tos3("system is little endian"));
    18. x = 1;
    19. #endif
    20. ;
    21. #ifdef TARGET_ORDER_IS_BIG
    22. println(tos3("system is big endian"));
    23. x = 2;
    24. #endif
    25. ;

    内联汇编代码

    1. //V代码
    2. fn main() {
    3. a := 10
    4. b := 0
    5. unsafe { //unsafe代码块
    6. asm { //asm代码块,里面可以直接写汇编代码
    7. "movl %1, %%eax;"
    8. "movl %%eax, %0;"
    9. :"=r"(b)
    10. :"r"(a)
    11. :"%eax"
    12. }
    13. }
    14. println(a) //返回10
    15. println(b) //返回10,直接通过汇编代码修改了b的值
    16. e := 0
    17. unsafe {
    18. asm {
    19. "movl $5, %0"
    20. :"=a"(e)
    21. }
    22. }
    23. println(e) //返回5,直接通过汇编代码修改了e的值
    24. }
    25. //C代码
    26. void main__main() {
    27. int a = 10;
    28. int b = 0;
    29. {
    30. asm("movl %1, %%eax;"
    31. "movl %%eax, %0;"
    32. : "=r"(b)
    33. : "r"(a)
    34. : "%eax");
    35. ;
    36. };
    37. /*opt*/ printf("%d\n", a);
    38. /*opt*/ printf("%d\n", b);
    39. int e = 0;
    40. {
    41. asm("movl $5, %0" : "=a"(e));
    42. ;
    43. };
    44. }