经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » 程序设计 » C 语言 » 查看文章
c语言中if语句是怎么变成汇编代码的详解
来源:jb51  时间:2021/11/24 11:07:45  对本文有异议

?1. 要编译的测试代码:?

  1. int a;
  2. int b = 3;
  3.  
  4. int main(void)
  5. {
  6. if (3)
  7. a = 4;
  8. else
  9. b = 5;
  10. }

2. 词法分析

  词法分析将c源代码解析成一个个的token。

  关键的,将if两个字符解析成一个if token,后续语法分析的输入就从两个字符减少为1个token,减小了语法分析的难度。

3. 语法分析

  1. if (equal(tok, "if")) {
  2. Node *node = new_node(ND_IF, tok);
  3. tok = skip(tok->next, "(");
  4. node->cond = expr(&tok, tok);
  5. tok = skip(tok, ")");
  6. node->then = stmt(&tok, tok);
  7. if (equal(tok, "else"))
  8. node->els = stmt(&tok, tok->next);
  9. *rest = tok;
  10. return node;
  11. }

如果当前处理的token是if,则

3.1 创建新的类型为ND_IF的node。

3.2 跳过if后面的"("。

3.3 调用expr函数解析if语句()中的表达式,并将解析结果存储在node->cond。

3.4 跳过“)”。

3.5 调用stmt处理then语句块中的语句,这里是处理"a = 4;",将解析结果存储在node->then。

3.6 如果if语句还有else部分,则调用stmt处理else语句块中的语句,这里是处理"b = 5;",将解析结果存储在node->els。

3.7 node->cond,node->then,node->els都为node节点。

4. 代码生成

  1. switch (node->kind) {
  2. case ND_IF: {
  3. int c = count();
  4. gen_expr(node->cond);
  5. cmp_zero(node->cond->ty);
  6. println(" je .L.else.%d", c);
  7. gen_stmt(node->then);
  8. println(" jmp .L.end.%d", c);
  9. println(".L.else.%d:", c);
  10. if (node->els)
  11. gen_stmt(node->els);
  12. println(".L.end.%d:", c);
  13. return;
  14. }
  15. ...

如果当前处理的node节点类型为ND_IF,则

4.1 gen_expr

这个函数处理if语句的条件部分,这里是处理3。判断node节点为NUM,会生成汇编语句"mov? ? ?rax, 3",将3载入rax寄存器。

4.2 cmp_zero

cmp_zero会生成汇编语句"cmp? ? ?eax, 0",比较3和0。

4.3 println(" je .L.else.%d", c);

该语句会生成汇编代码" je .L.else.1",当上条比较语句中eax为0时会执行跳转,跳转到else分支运行。这里由于eax为3,所以不跳转。

4.4 gen_stmt(node->then);

这条语句会将then分支中的语句解析为汇编源码,这里是"a = 4;",这条语句是表达式语句,所以会调用gen_expr函数。

4.4.1 gen_expr

"lea? ? ?rax, a",将a的地址载入rax寄存器中。

"push rax",将rax入栈。

"mov? ? ?rax, 4",将4载入rax寄存器中。

"pop? ? ?rdi",将变量a的地址载入rdi寄存器。

"mov? ? ?[rdi], eax",将4写入变量a。?

4.5 println(" jmp .L.end.%d", c);

执行完then分支代码后跳转到下一条语句处执行。

4.6 println(".L.else.%d:", c);

插入一条标签,表示else分支代码的开始,如果if语句条件为0会跳转到这。

4.7 gen_stmt(node->els);

生成else分支代码,处理"b = 5;"。

"lea? ? ?rax, b",将变量b的地址载入rax寄存器。

"push? ? rax",将rax寄存器入栈。

"mov? ? ?rax, 5",将5载入rax寄存器。

"pop? ? ?rdi",将b的地址载入rdi寄存器。

"mov? ? ?[rdi], eax",将5写入变量b中。

4.8 println(".L.end.%d:", c);

插入一条标签,表示if语句的结束,then分支语句执行完成后跳转到这里。

总结

到此这篇关于c语言中if语句是怎么变成汇编代码的文章就介绍到这了,更多相关c语言if语句变成汇编代码内容请搜索w3xue以前的文章或继续浏览下面的相关文章希望大家以后多多支持w3xue!

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号