qemu tcg代码执行流程

2023-05-16

转自:  http://blog.csdn.net/alloc7/article/details/7719823

一.qemu简介

         qemu是使用动态二进制翻译的cpu模拟器,它支持两种运行模式:全系统模拟和用户态模拟。在全系统模拟下,qemu可以模拟处理器和各种外设,可以运行操作系统。用户态可以运行为另外一种cpu编译的进程,前提是两者运行的os要一致。qemu使用了动态二进制翻译将targetinstruction翻译成hostinstruction,完成这个工作的是tcg模块。为了移植性和通用性方面的考虑,qemu定义了mirco-op,首先qemu会将targetinstruction翻译成mirco-op,然后tcg将mirco-op翻译成host instruction。

Qemu代码翻译流程:target instruction ->micro-op->tcg->host instruction

2.qemu代码执行流程:

    1. 这部分主要是创建了一个为执行tcg翻译和执行的线程,它的函数是qemu_tcg_cpu_thread_fn,这个函数会调用tcg_exec_all,最后cpu_exec.   

main
cpu_init
qemu_init_vcpu
qemu_tcg_init_vcpu

qemu_tcg_cpu_thread_fn

 

     2.执行主函数(cpu_exec)

                主要是处理中断异常, 找到代码翻译块,然后执行.

 

[cpp]  view plain copy
  1. for(;;)  
  2. process interruptrequest;  
  3.   
  4. tb_find_fast();  
  5.   
  6. tcg_qemu_tb_exec(tc_ptr);  
  7.  

 

 

        qemu会将翻译好到代码块暂存起来,因此首先会去查看该pc对应的代码是否已经翻译,如果已经存在直接返回,否则就进入tb_find_slow,进行翻译。

 

[cpp]  view plain copy
  1. 139 static inline TranslationBlock *tb_find_fast(CPUArchState *env)  
  2. 140  
  3. 141     TranslationBlock *tb;  
  4. 142     target_ulong cs_base, pc;  
  5. 143     int flags;  
  6. 144   
  7. 145       
  8. 148     cpu_get_tb_cpu_state(env, &pc, &cs_base, &flags);  
  9. 149     tb env->tb_jmp_cache[tb_jmp_cache_hash_func(pc)];  
  10. 150     if (unlikely(!tb || tb->pc != pc || tb->cs_base != cs_base ||  
  11. 151                  tb->flags != flags))  
  12. 152         tb tb_find_slow(env, pc, cs_base, flags);  
  13. 153      
  14. 154     return tb;  
  15. 155  

 

       进入tb_find_slow后会调用tb_gen_code,首先分配TranslationBlock描述符,将要翻译的pc等信息记录下来,然后调用cpu_gen_code,这个函数完成代码翻译工作。qemu将翻译好的代码存在一个缓冲区里面。

[cpp]  view plain copy
  1. 1029 TranslationBlock *tb_gen_code(CPUArchState *env,  
  2. 1030                               target_ulong pc, target_ulong cs_base,  
  3. 1031                               int flags, int cflags)  
  4. 1032            
  5. 1033     TranslationBlock *tb;  
  6. 1034     uint8_t *tc_ptr;  
  7. 1035     tb_page_addr_t phys_pc, phys_page2;  
  8. 1036     target_ulong virt_page2;  
  9. 1037     int code_gen_size;  
  10. 1038      
  11. 1039     phys_pc get_page_addr_code(env, pc);  
  12. 1040     tb tb_alloc(pc);  
  13. 1041     if (!tb)  
  14. 1042           
  15. 1043         tb_flush(env);  
  16. 1044           
[cpp]  view plain copy
  1. 1045         tb tb_alloc(pc);  
  2. 1046           
  3. 1047         tb_invalidated_flag 1;  
  4. 1048      
  5. 1049     tc_ptr code_gen_ptr;  
  6. 1050     tb->tc_ptr tc_ptr;  
  7. 1051     tb->cs_base cs_base;  
  8. 1052     tb->flags flags;  
  9. 1053     tb->cflags cflags;  
  10. 1054     cpu_gen_code(env, tb, &code_gen_size);  
  11. 1055     code_gen_ptr (void *)(((uintptr_t)code_gen_ptr code_gen_size  
  12. 1056                              CODE_GEN_ALIGN 1) ~(CODE_GEN_ALIGN 1));  
  13. 1057   
  14. 1058       
  15. 1059     virt_page2 (pc tb->size 1) TARGET_PAGE_MASK;  
  16. 1060     phys_page2 -1;  
  17. 1061     if ((pc TARGET_PAGE_MASK) != virt_page2)  
  18. 1062         phys_page2 get_page_addr_code(env, virt_page2);  
  19. 1063      
  20. 1064     tb_link_page(tb, phys_pc, phys_page2);  
  21. 1065     return tb;  
  22. 1066  

 

      在cpu_gen_code里面首先是将targetinstruction翻译成micro-op,然后将mirco-op翻译成host机器码。

 

[cpp]  view plain copy
  1. 54 int cpu_gen_code(CPUArchState *env, TranslationBlock *tb, int *gen_code_size_ptr)  
  2.  55  
  3.  56     TCGContext *s &tcg_ctx;  
  4.  57     uint8_t *gen_code_buf;  
  5.  58     int gen_code_size;  
  6.  59 #ifdef CONFIG_PROFILER  
  7.  60     int64_t ti;  
  8.  61 #endif  
  9.  62   
  10.  63 #ifdef CONFIG_PROFILER  
  11.  64     s->tb_count1++;   
  12.  66     ti profile_getclock();  
  13.  67 #endif  
  14.  68     tcg_func_start(s);  
  15.  69   
  16.  70     gen_intermediate_code(env, tb);  
  17.  71   
  18.  72       
  19.  73     gen_code_buf tb->tc_ptr;  
  20.  74     tb->tb_next_offset[0] 0xffff;  
  21.  75     tb->tb_next_offset[1] 0xffff;  
  22.  76     s->tb_next_offset tb->tb_next_offset;  
  23.  77 #ifdef USE_DIRECT_JUMP  
  24.  78     s->tb_jmp_offset tb->tb_jmp_offset;  
  25.  79     s->tb_next NULL;  
  26.  80 #else  
  27.  81     s->tb_jmp_offset NULL;  
  28.  82     s->tb_next tb->tb_next;  
  29.  83 #endif  
  30.  84   
  31.  85 #ifdef CONFIG_PROFILER  
  32.  86     s->tb_count++;  
  33.  87     s->interm_time += profile_getclock() ti;  
  34.  88     s->code_time -= profile_getclock();  
  35.  89 #endif  
  36.  90     gen_code_size tcg_gen_code(s, gen_code_buf);  
  37.  91     *gen_code_size_ptr gen_code_size;  
  38.  92 #ifdef CONFIG_PROFILER  
  39.  93     s->code_time += profile_getclock();  
  40.  94     s->code_in_len += tb->size;  
  41.  95     s->code_out_len += gen_code_size;  
  42.  96 #endif  
  43.  97   
  44.  98 #ifdef DEBUG_DISAS  
  45.  99     if (qemu_loglevel_mask(CPU_LOG_TB_OUT_ASM))  
  46. 100         qemu_log("OUT: [size=%d]\n", *gen_code_size_ptr);  
  47. 101         log_disas(tb->tc_ptr, *gen_code_size_ptr);  
  48. 102         qemu_log("\n");  
  49. 103         qemu_log_flush();  
  50. 104      
  51. 105 #endif  
  52. 106     return 0;  
  53. 107  

 

       qemu将target翻译成中间码时,将操作码和操作数分开存储,分别存在gen_opc_buf和gen_opparam_buf中。翻译的过程就是不断向gen_opc_buf和gen_opparam_buf中填充操作码和操作数。接下来就是tcg_gen_code.

 

[cpp]  view plain copy
  1. 2175 int tcg_gen_code(TCGContext *s, uint8_t *gen_code_buf)  
  2. 2176  
  3. 2177 #ifdef CONFIG_PROFILER  
  4. 2178      
  5. 2179         int n;  
  6. 2180         (gen_opc_ptr gen_opc_buf);  
  7. 2181         s->op_count += n;  
  8. 2182         if (n s->op_count_max)  
  9. 2183             s->op_count_max n;  
  10. 2184   
  11. 2185         s->temp_count += s->nb_temps;  
  12. 2186         if (s->nb_temps s->temp_count_max)  
  13. 2187             s->temp_count_max s->nb_temps;  
  14. 2188      
  15. 2189 #endif  
  16. 2190   
  17. 2191     tcg_gen_code_common(s, gen_code_buf, -1);  
  18. 2192   
  19. 2193       
  20. 2194     flush_icache_range((tcg_target_ulong)gen_code_buf,  
  21. 2195                        (tcg_target_ulong)s->code_ptr);  
  22. 2196   
  23. 2197     return s->code_ptr  gen_code_buf;  
  24. 2198  

 

      tcg_gen_code的工作是将中间码翻译成host机器码,它的主要函数是tcg_gen_code_common.

 

[cpp]  view plain copy
  1. 2045 static inline int tcg_gen_code_common(TCGContext *s, uint8_t *gen_code_buf,  
  2. 2046                                       long search_pc)  
  3. 2047  
  4. 2048     TCGOpcode opc;  
  5. 2049     int op_index;  
  6. 2050     const TCGOpDef *def;  
  7. 2051     unsigned int dead_args;  
  8. 2052     const TCGArg *args;  
  9. 2053   
  10. 2054 #ifdef DEBUG_DISAS  
  11. 2055     if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP)))  
  12. 2056         qemu_log("OP:\n");  
  13. 2057         tcg_dump_ops(s);  
  14. 2058         qemu_log("\n");  
  15. 2059      
  16. 2060 #endif  
  17. 2061   
  18. 2062 #ifdef USE_TCG_OPTIMIZATIONS  
  19. 2063     gen_opparam_ptr  
  20. 2064         tcg_optimize(s, gen_opc_ptr, gen_opparam_buf, tcg_op_defs);  
  21. 2065 #endif  
  22. 2066   
  23. 2067 #ifdef CONFIG_PROFILER  
  24. 2068     s->la_time -= profile_getclock();  
  25. 2069 #endif  
  26. 2070     tcg_liveness_analysis(s);  
  27. 2071 #ifdef CONFIG_PROFILER  
  28. 2072     s->la_time += profile_getclock();  
  29. 2073 #endif  
  30. 2074   
  31. 2075 #ifdef DEBUG_DISAS  
  32. 2076     if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP_OPT)))  
  33. 2077         qemu_log("OP after liveness analysis:\n");  
  34. 2078         tcg_dump_ops(s);  
  35. 2079         qemu_log("\n");  
  36. 2080      
  37. 2081 #endif  
  38. 2082   
  39. 2083     tcg_reg_alloc_start(s);  
  40. 2084   
  41. 2085     s->code_buf gen_code_buf;  
  42. 2086     s->code_ptr gen_code_buf;  
  43. 2087   
  44. 2088     args gen_opparam_buf;  
  45.  2089     op_index 0;  
  46. 2090   
  47. 2091     for(;;)  
  48. 2092         opc gen_opc_buf[op_index];  
  49. 2093 #ifdef CONFIG_PROFILER  
  50. 2094         tcg_table_op_count[opc]++;  
  51. 2095 #endif  
  52. 2096         def &tcg_op_defs[opc];  
  53. 2097 #if  
  54. 2098         printf("%s: %d %d %d\n", def->name,  
  55. 2099                def->nb_oargs, def->nb_iargs, def->nb_cargs);  
  56. 2100         //        dump_regs(s);  
  57. 2101 #endif  
  58. 2102         switch(opc)  
  59. 2103         case INDEX_op_mov_i32:  
  60. 2104 #if TCG_TARGET_REG_BITS == 64  
  61. 2105         case INDEX_op_mov_i64:  
  62. 2106 #endif  
  63. 2107             dead_args s->op_dead_args[op_index];  
  64. 2108             tcg_reg_alloc_mov(s, def, args, dead_args);  
  65. 2109             break;  
  66. 2110         case INDEX_op_movi_i32:  
  67. 2111 #if TCG_TARGET_REG_BITS == 64  
  68. 2112         case INDEX_op_movi_i64:  
  69. 2113 #endif  
  70. 2114             tcg_reg_alloc_movi(s, args);  
  71. 2115             break;  
  72. 2116         case INDEX_op_debug_insn_start:  
  73. 2117               
  74. 2118             break;  
  75. 2119         case INDEX_op_nop:  
  76. 2120         case INDEX_op_nop1:  
  77. 2121         case INDEX_op_nop2:  
  78. 2122         case INDEX_op_nop3:  
  79. 2123             break;  
  80. 2124         case INDEX_op_nopn:  
  81. 2125             args += args[0];  
  82. 2126             goto next;  
  83. 2127         case INDEX_op_discard:  
  84. 2128              
  85.  2129                 TCGTemp *ts;  
  86. 2130                 ts &s->temps[args[0]];  
  87. 2131                   
  88. 2132                 if (!ts->fixed_reg)  
  89. 2133                     if (ts->val_type == TEMP_VAL_REG)  
  90. 2134                         s->reg_to_temp[ts->reg] -1;  
  91. 2135                     ts->val_type TEMP_VAL_DEAD;  
  92. 2136                  
  93. 2137              
  94. 2138             break;  
  95. 2139         case INDEX_op_set_label:  
  96. 2140             tcg_reg_alloc_bb_end(s, s->reserved_regs);  
  97. 2141             tcg_out_label(s, args[0], s->code_ptr);  
  98. 2142             break;  
  99. 2143         case INDEX_op_call:  
  100. 2144             dead_args s->op_dead_args[op_index];  
  101. 2145             args += tcg_reg_alloc_call(s, def, opc, args, dead_args);  
  102. 2146             goto next;  
  103. 2147         case INDEX_op_end:  
  104. 2148             goto the_end;  
  105. 2149         default:  
  106. 2150               
  107. 2151             if (def->flags TCG_OPF_NOT_PRESENT)  
  108. 2152                 tcg_abort();  
  109. 2153              
  110. 2154               
  111. 2157             dead_args s->op_dead_args[op_index];  
  112. 2158             tcg_reg_alloc_op(s, def, opc, args, dead_args);  
  113. 2159             break;  
  114. 2160          
  115. 2161         args += def->nb_args;  
  116. 2162     next:  
  117. 2163         if (search_pc >= && search_pc s->code_ptr gen_code_buf)  
  118. 2164             return op_index;  
  119. 2165          
  120. 2166         op_index++;  
  121. 2167 #ifndef NDEBUG  
  122. 2168         check_regs(s);  
  123. 2169 #endif  
  124. 2170      
  125.  2171  the_end:  
  126. 2172     return -1;  
  127. 2173  

 

       大部分执行default分支,tcg_reg_alloc_op主要是分析该指令的输入、输出约束,根据这些约束分配寄存器等,然后调用tcg_out_op将该中间码翻译成host机器码。

 

3.翻译代码块的执行

     代码块翻译好之后,主函数调用tcg_qemu_tb_exec,该函数会进入tcg的入口函数。

 

以host是arm为例,入口函数主要是保存寄存器的状态,然后将tcg_qemu_tb_exec传进来的第一的参数(env)给TCG_AREG0,然后跳转至tb_ptr,开始执行代码。同时代码执行的返回地址也确定了,返回后恢复之前保存的状态。

以host 是arm 为例,入口函数主要是保存寄存器的状态,然后将tcg_qemu_tb_exec 传进来的第一的参数(env) 给TCG_AREG0 ,然后跳转至tb_ptr ,开始执行代码。同时代码执行的返回地址也确定了,返回后恢复之前保存的状态。
[cpp]  view plain copy
  1. 100 #define tcg_qemu_tb_exec(env, tb_ptr)  
  2. 101     ((long __attribute__ ((longcall))  
  3. 102       (*)(void *, void *))code_gen_prologue)(env, tb_ptr)  

      code_gen_prologue是tcg的入口函数,在tcg初始化的时候会生成相应的代码.

         以host是arm为例,入口函数主要是保存寄存器的状态,然后将tcg_qemu_tb_exec传进来的第一的参数(env)给TCG_AREG0,然后跳转至tb_ptr,开始执行代码。同时代码执行的返回地址也确定了,返回后恢复之前保存的状态。

 

[cpp]  view plain copy
  1. 1881 static void tcg_target_qemu_prologue(TCGContext *s)  
  2. 1882  
  3. 1883       
  4. 1886       
  5. 1887       
  6. 1888     tcg_out32(s, (COND_AL << 28) 0x092d5ff0);  
  7. 1889   
  8. 1890     tcg_out_mov(s, TCG_TYPE_PTR, TCG_AREG0, tcg_target_call_iarg_regs[0]);  
  9. 1891   
  10. 1892     tcg_out_bx(s, COND_AL, tcg_target_call_iarg_regs[1]);  
  11. 1893     tb_ret_addr s->code_ptr;  
  12. 1894       
  13. 1895       
  14. 1896     tcg_out32(s, (COND_AL << 28) 0x08bd9ff0);  
  15. 1897     


 











更多 0
  • 上一篇linux启动分析
  • 下一篇qemu内存访问分析
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

qemu tcg代码执行流程 的相关文章

  • Ubuntu搭建开发openchannelssd的qemu的虚拟机

    1 安装带有NVMe支持的qemu QEMU Installation QEMU support for Open Channel SSDs is based on top of Keith Busch s qemu nvme branch
  • QEMU虚拟机中如何安装Virtio驱动

    在计算机虚拟化中 Virtio是一种半虚拟化解决方案 即需要对Guest OS进行一定的修改 安装相应的驱动程序 能够对虚拟机的I O性能进行大幅的提升 在QEMU KVM的环境中 Virtio的后端驱动由QEMU程序提供 不需要额外的安装
  • macbook m1 用qemu安装arm版win10

    一共参考了5篇文章 感谢这些作者 https forums macrumors com threads success virtualize windows 10 for arm on m1 with alexander grafs qem
  • win11 使用 QEMU 配置龙芯 3A5000 虚拟环境

    01 下载资源 本实验使用资源 开源模拟器qemu 下载地址 qemu w64 setup 20230822 exe loongarch 固件下载 QEMU EFI 8 0 fd loongarch 基本镜像下载 archlinux loo
  • 基於RISC-V QEMU 仿真運行Linux 系統環境搭建

    前言 文章詳細說明如何從堶零開始基於RISC V QEMU 仿真運行Linux 系統環境搭建 是Linux 小白入門教程不二之選 歡迎留言討論 轉發請注明原文出處 1 準備QEMU 仿真環境 RISC V 64bits 安裝包下載地址 ht
  • 从零开始制作Linux

    提到制作Linux 大家都能想到如雷贯耳 大名鼎鼎的Linux from scratch 但Linux from scratch的复杂性不是普通人能轻易掌握的 对于初学者来说 任何步骤出现不一致 会让初学者遇到挫拆 攻破LFS的信心越来越低
  • 远程 gdb 调试不会在断点处停止

    我在调试修改后的 Linux 3 11 0 内核时遇到问题 为了调试代码 我使用 GDB 7 6 QEMU 1 6 5 Linux内核3 11 0 我的系统有 Intel R Core TM i7 2760QM CPU 2 40GHz 运行
  • 在linux下构建edk2

    我开始用 edk2 编写一个小而简单的应用程序 因此 要编写一个简单的 edk2 UEFI 应用程序 我是这样开始的 git克隆https github com tianocore edk2 git edksetup sh BaseTool
  • Gem5 中与 ARM 裸机的 UART 通信

    我目前正在使用 Gem5 我必须通过 UART 从我的主机访问 ARMv8 裸机选项 所以我尝试了很多方法 但我还没有准备好 您能否让我知道 如何在裸机类型编程中将主机的串行端口映射到 ARMv8 的串行端口 任何帮助 将不胜感激 工作设置
  • 升级到 macOS Catalina 后 Qemu 没有响应

    将我的 Mac 升级到 Catalina 后 我无法再使用 qemu 每当我尝试启动它时 它就会挂起 当 qemu 窗口处于活动状态时 菜单栏也不会响应 跑步qemu system i386 help不过确实有效 Qemu版本 4 1 0
  • 运行Qemu后只是黑屏

    我刚刚安装了 QEMU 并编译了支持 ARM 的 Linux 内核 但是当我运行下面的命令时 qemu system arm M versatilepb m 128M kernel home arit QEMU linux 3 8 4 ar
  • QEMU、无可启动设备、Linux 的 Windows 子系统

    我正在学习如何构建基本的操作系统内核https intermezzos github io https intermezzos github io 我已经创建了我的 iso文件 我现在正在运行qemu system x86 64 cdrom
  • 挂载Android模拟器创建的qcow2镜像

    我正在尝试挂载 Android 模拟器创建的 userdata qemu img qcow2 文件 以下过程不起作用 sudo qemu nbd c dev nbd0 android avd Pixel C API 27 avd userd
  • 在 qemu 中使用 GDB 调试 Linux 内核无法命中函数或给定地址

    我试图在 qemu 环境中使用 GDB 逐步理解内核启动顺序 以下是我的设置 在一个终端中我正在运行 Qemu arm bin qemu system arm M vexpress a9 dtb arch arm boot dts vexp
  • 如何使用QEMU学习ARM Linux内核开发?

    我想学习它 比如开发一些设备驱动程序等 并为此使用 QEMU 因为我没有像 beagle 板这样的 ARM 硬件板 你们有什么建议 我可以使用 Qemu 模拟器来学习 ARM 目标上的 Linux 内核吗 或者我应该尝试的任何其他选择 这取
  • 了解 QEMU 的好来源是什么?

    您会推荐什么书或网站来了解 QEMU 我想查看一些使用示例以及如何使用 API 最佳资源 主要 QEMU 使用文档 http wiki qemu org Manual Qemu 手册页 http manpages ubuntu com ma
  • Qemu-KVM:将访客物理地址转换为主机虚拟/主机物理地址

    我正在做一个需要翻译的项目qemu guest物理地址到主机虚拟 物理地址 我正在使用 VMI 虚拟机自省 来自省 qemu 进程 KVM VM 并读取存储在 virtio 环缓冲区描述符中的来宾物理地址 因此 我正在寻找一种简单的方法来将
  • 4.1 android模拟器未检测到sd卡

    我曾经使用 4 1 kitkat x86 android 模拟器和 SD 卡进行测试 将 Android Studio 升级到 2 3 后 我无法再访问 android 中提供的 SD 卡 这使得我无法进行测试 谷歌还没有对此的答案 我也没
  • qemu kvm:如何获取性能监控中断?

    我在操作系统内核中编写了一些函数 以便在指令计数器溢出时发出性能监控中断 PMI 它在我的机器 Intel core i5 上运行良好 但是当我使用 qemu 在 qemu 上运行它时 qemu system x86 64 enable k
  • Qemu flash 启动不起作用

    我有一本相当旧的 2009 年出版 嵌入式 ARM Linux 书 其中使用u boot and qemu 的用法qemu与u boot书中对二进制的解释如下 qemu system arm M connex pflash u boot b

随机推荐

  • WSL运行python程序关于路径的坑

    安装了wsl xff08 Windows下的Linux子系统 xff09 xff0c 跑python代码时 xff0c 发现路径有问题 总结来说 xff0c 如果是跑linux里的代码 xff0c 那么其中的绝对路径就按linux的地址解析
  • 【基础编程题】Java基础====键盘输入学生成绩,计算后按总分高低顺序存入磁盘文件txt

    要求 xff1a 有五个学生 xff0c 每个学生有3门课程的成绩从键盘输入以上数据 xff08 包括姓名 xff0c 三门课成绩 xff09 输入的格式 xff1a 如 xff1a zhangsan 30 40 60计算出总成绩 xff0
  • MySQL 配置文件位置及命名。

    MySQL 配置文件位置及命名 使用 mysqladmin 或 mysql xff0c 会提示 MySQL 加载配置文件的顺序及文件命名规范 span class token keyword Default span options are
  • Codeforces 1419B. Stairs 递归

    Codeforces 1419B Stairs 递归 原题链接https codeforces com problemset problem 1419 B 样例 输入 5 2 1 49 5 20 50 6 20 50 5 3 8 9 13
  • dos中定义变量与引用变量以及四则运算

    在dos中使用set定义变量 xff1a set a 61 8 注意等号两边没有空格 引用变量如 xff1a echo a 将打印a的值 dos中要使用算术运算 xff0c 需要使用 set 命令 xff1a set a val 61 3
  • Python将计算结果拷贝至粘贴板

    前言 xff1a 我们知道在使用ctrl 43 c复制文字时 xff0c 实际是将文字复制到了粘贴板中 xff08 内存 xff09 xff0c 而在实际应用中 xff0c 除了将Python的计算结果打印外 xff0c 有时还想进行自动复
  • Java反射——通过Java反射机制设置属性值

    本示例使用Java反射机制分别设置当前类的private public属性以及其父类的private属性来说明如何通过Java反射机制设置属性值 xff08 注 xff1a 设置继承的父类属性时 xff0c 无法通过当前类的Class对象直
  • 7-9 选择法排序之过程 (15 分)

    7 9 选择法排序之过程 15 分 本题要求使用选择法排序 xff0c 将给定的n个整数从小到大排序后输出 xff0c 并输出排序过程中每一步的中间结果 选择排序的算法步骤如下 xff1a 第0步 xff1a 在未排序的n个数 xff08
  • Debian配置清华源

    确定debian的系统版本 plc 64 debian cat etc os release PRETTY NAME 61 34 Debian GNU Linux 9 stretch 34 NAME 61 34 Debian GNU Lin
  • AAC音频编码格式介绍

    一 概述及分类 AAC Advanced Audio Coding 的缩写 xff0c 中文称为 高级音频编码 xff0c 被手机界称为 21世纪数据压缩方式 xff0c AAC所采用的运算方式是与MP3的运算有所不同 xff0c AAC同
  • Ubuntu系统失败之----安装U盘不能存放其它文件

    Ubuntu安装失败的经验贴 背景 xff1a 笔者在数月之前制作了一个Ubuntu 14 4系统安装盘 xff08 当时把U盘格式化 制作了引导并且拷贝了镜像 xff09 U盘的特点是除了系统相关文件之外没有其它任何文件 当时在三台联想笔
  • 结构体sizeof不想字节对齐

    问题描述 xff1a 笔者在做一个项目 xff1a 硬件要访问内存中按照Spec格式定义 的一段数据包 在C语言中一般使用结构体初始化这个数据包 xff0c 因为可以方便配置各个字段 但结构体默认需要字节对齐的 xff08 sizeof和实
  • C/C++语言static修饰函数的作用

    描述 xff1a 在C C 43 43 语言程序中 xff0c 特别是的大型程序 xff0c 函数名前往往用static关键词修饰 作用 xff1a 主要的作用是避免命名冲突 static函数与一般函数作用域不同 xff0c 仅在本文件有效
  • ubuntu16.04升级18.04(再次作死)

    继上次升级glibc版本作了一次大死后 xff0c 手又痒了 xff0c 又觉得我可以了 来继续升级ubuntu16 04升级到 ubuntu18 04 最主要的原因是ubuntu自带的python只到了3 5的版本 而我需要python3
  • 初始C语言——统计字符串中的字母,数字和其他符号 的个数

    define CRT SECURE NO WARNINGS 1 防止visual studio2013以上版本scanf报错 xff0c vc6 0环境可忽略 include lt stdio h gt int main int a 61
  • Linux下开发调试中大型C语言代码-如何提高效率

    背景 xff1a 在Linux下开发中大型C语言程序 xff08 包括编写 编译调试等步骤 xff09 时 xff0c 尤其大部分代码都是原创的情况下 以下的经验往往能提高调试效率 经验 xff1a xff08 1 xff09 Linux命
  • 《C语言中分配了动态内存后一定要释放吗?》

    问 xff1a 比如main函数里有一句 malloc 后面没有free 1 那么当main结束后 xff0c 动态分配的内存不会随之释放吗 xff1f 2 如果程序结束能自动释放 xff0c 那么还加上free xff08 xff09 x
  • Qemu使用心得

    使用Qemu的心得体会如下 xff1a xff08 1 xff09 在QEMU源码中增加自己的 c实现 xff0c 编译后出现很多个错误如 xff1a error storage class specified for parameter
  • 转载:malloc和free底层实现

    转载 xff1a malloc和free底层实现 内存管理内幕 Linux内存管理 xff1a Malloc 本文引用了下面这篇文章 xff0c 读完下面 xff0c 应该读下上面两篇文章 xff0c 其中 xff0c 内存管理内幕 提供了
  • qemu tcg代码执行流程

    转自 xff1a http blog csdn net alloc7 article details 7719823 一 qemu简介 qemu是使用动态二进制翻译的cpu模拟器 xff0c 它支持两种运行模式 xff1a 全系统模拟和用户