交流
商城
MCN
登入
注册
首页
提问
分享
讨论
建议
公告
动态
发表新帖
发表新帖
3 判断
分享
未结
0
925
李延
LV6
2022-06-07
悬赏:20积分
# 1 判断 主要包括 if于else语句 , 三元运算符,已经switch语句 # 2 if与else ```c #include <stdio.h> int sum(int a,int b){ if(a >b){ return 1; } else{ return 0; } } int main() { int num = sum(1,2); printf("sum is %d!\n",num); return 0; } ``` ```asm .file "if.c" .text .globl sum .type sum, @function sum: .LFB11: .cfi_startproc cmpl %esi, %edi jle .L3 movl $1, %eax ret .L3: movl $0, %eax ret .cfi_endproc .LFE11: .size sum, .-sum .section .rodata.str1.1,"aMS",@progbits,1 .LC0: .string "sum is %d!\n" .text .globl main .type main, @function main: .LFB12: .cfi_startproc subq $8, %rsp .cfi_def_cfa_offset 16 movl $2, %esi movl $1, %edi call sum movl %eax, %esi movl $.LC0, %edi movl $0, %eax call printf movl $0, %eax addq $8, %rsp .cfi_def_cfa_offset 8 ret .cfi_endproc .LFE12: .size main, .-main .ident "GCC: (GNU) 4.8.5 20150623 (Red Hat 4.8.5-44)" .section .note.GNU-stack,"",@progbits ``` # 3 三元表达式 编译后与上面if语句一样。 ```c #include <stdio.h> int sum(int a,int b){ return a>b ? 1:0; } int main() { int num = sum(1,2); printf("sum is %d!\n",num); return 0; } ``` ```asm .file "if2.c" .text .globl sum .type sum, @function sum: .LFB11: .cfi_startproc cmpl %esi, %edi jle .L3 movl $2, %eax ret .L3: movl $1, %eax ret .cfi_endproc .LFE11: .size sum, .-sum .section .rodata.str1.1,"aMS",@progbits,1 .LC0: .string "sum is %d!\n" .text .globl main .type main, @function main: .LFB12: .cfi_startproc subq $8, %rsp .cfi_def_cfa_offset 16 movl $2, %esi movl $1, %edi call sum movl %eax, %esi movl $.LC0, %edi movl $0, %eax call printf movl $0, %eax addq $8, %rsp .cfi_def_cfa_offset 8 ret .cfi_endproc .LFE12: .size main, .-main .ident "GCC: (GNU) 4.8.5 20150623 (Red Hat 4.8.5-44)" .section .note.GNU-stack,"",@progbits ``` # 4 switch ```c #include <stdio.h> int sum(int a) { int b; switch (a) { case 1: b = 1; break; case 1: b = 2; break; case 1: b = 3; break; case 1: b = 4; case 1: b = 5; break; default: b = 6; break; } return b; } int main() { int num = sum(x); printf("sum is %d!\n", num); return 0; } ``` ```asm .file "switch.c" .text .globl sum .type sum, @function sum: .LFB11: .cfi_startproc cmpl $5, %edi ja .L2 movl %edi, %edi jmp *.L4(,%rdi,8) .section .rodata .align 8 .align 4 .L4: .quad .L2 .quad .L3 .quad .L8 .quad .L6 .quad .L7 .quad .L7 .text .L3: movl $1, %eax ret .L6: movl $3, %eax ret .L7: movl $5, %eax ret .L2: movl $6, %eax ret .L8: movl $2, %eax ret .cfi_endproc .LFE11: .size sum, .-sum .section .rodata.str1.1,"aMS",@progbits,1 .LC0: .string "sum is %d!\n" .text .globl main .type main, @function main: .LFB12: .cfi_startproc subq $8, %rsp .cfi_def_cfa_offset 16 movl $4, %edi call sum movl %eax, %esi movl $.LC0, %edi movl $0, %eax call printf movl $0, %eax addq $8, %rsp .cfi_def_cfa_offset 8 ret .cfi_endproc .LFE12: .size main, .-main .ident "GCC: (GNU) 4.8.5 20150623 (Red Hat 4.8.5-44)" .section .note.GNU-stack,"",@progbits ``` ## 3.1 解析 首先我们代码先式通过 ```asm cmpl $5, %edi ``` 而 5 就是我们case里的做大值,当参数大于5时,也就是 default 情况,直接跳转到L2 ```asm ja .L2 ``` 但对于其他情况,使用 ```asm jmp *.L4(,%rdi,8) ``` 这个我们可以看成一个间接寻址,意思为 .L4的地址 + rdi * 8 而.L4 我们可以看为一个数组 ```asm .L4: .quad .L2 .quad .L3 .quad .L8 .quad .L6 .quad .L7 .quad .L7 .text ``` 每个元素是8个字节。进行跳转 # 5 跨度较大的switch 上面连续的switch ,如果跨度比较大的时候,会被编译为和if相似的情况 ```c #include <stdio.h> int sum(int a) { int b; switch (a) { case 101: b = 1; break; case 230: b = 2; break; case 347: b = 3; break; case 473: b = 4; case 587: b = 5; break; default: b = 6; break; } return b; } int main() { int num = sum(101); printf("sum is %d!\n", num); return 0; } ``` ```asm .file "switch2.c" .text .globl sum .type sum, @function sum: .LFB11: .cfi_startproc cmpl $347, %edi je .L3 cmpl $347, %edi jg .L4 cmpl $101, %edi je .L5 cmpl $230, %edi je .L8 .p2align 4,,2 jmp .L2 .L4: cmpl $473, %edi je .L7 cmpl $587, %edi je .L7 jmp .L2 .L5: movl $1, %eax ret .L3: movl $3, %eax .p2align 4,,2 ret .L7: movl $5, %eax ret .L2: movl $6, %eax ret .L8: movl $2, %eax ret .cfi_endproc .LFE11: .size sum, .-sum .section .rodata.str1.1,"aMS",@progbits,1 .LC0: .string "sum is %d!\n" .text .globl main .type main, @function main: .LFB12: .cfi_startproc subq $8, %rsp .cfi_def_cfa_offset 16 movl $101, %edi call sum movl %eax, %esi movl $.LC0, %edi movl $0, %eax call printf movl $0, %eax addq $8, %rsp .cfi_def_cfa_offset 8 ret .cfi_endproc .LFE12: .size main, .-main .ident "GCC: (GNU) 4.8.5 20150623 (Red Hat 4.8.5-44)" .section .note.GNU-stack,"",@progbits ```
回帖
消灭零回复
提交回复
热议榜
java 相关知识分享
8
好的程序员与不好的程序员
6
写给工程师的十条精进原则
5
spring boot以jar包运行配置的logback日志文件没生成
5
一步一步分析SpringBoot启动源码(一)
5
MockMvc测试
5
【吐槽向】是不是有个吐槽的板块比较好玩
4
logstash jdbc同步mysql多表数据到elasticsearch
3
IntelliJ IDEA 优质License Server
3
.gitignore忽略规则
3
SpringBoot启动源码分析
3
一步一步分析SpringBoot启动源码(三)
3
2
一步一步分析SpringBoot启动源码(二)
2
积分不够将无法发表新帖
2
官方产品
Meta-Boot - 基于MCN
MCN - 快速构建SpringBoot应用
微信扫码关注公众号