c语言的逻辑与怎么编程,C语言逻辑与、逻辑或的编译

int main() {

int a, b;

int c = a && b;

int d = a || b;

return 0;

}

这样的一段非常简单的程序,编译器一般会如何实现它呢?

首先,x86架构的CPU没有逻辑与和逻辑或的指令,那么,对于逻辑与和逻辑或,编译器会如何将其转换为x86指令集下的指令序列呢?

使用gcc -S命令产生了编译产生的汇编代码。我通过在其中添加一些C风格的注释,帮助大家理解这段简单的代码。

.file"logic.c"

.text

.globlmain

.typemain, @function

main:

.LFB0:

.cfi_startproc

pushl%ebp

.cfi_def_cfa_offset 8

.cfi_offset 5, -8

movl%esp, %ebp //此时ebp寄存器保存了栈顶指针的位置(声明局部变量前)

.cfi_def_cfa_register 5

subl$16, %esp //栈顶指针上移16字节,即申请四个int类型变量的栈空间

cmpl$0, -4(%ebp) //-4(%ebp)为变量a,比较变量a与立即数0

je.L2 //如果相等则跳转到L2

cmpl$0, -8(%ebp) //否则比较变量b与立即数0

je.L2 //如果相等则跳转到L2

movl$1, %eax //否则eax寄存器设为1

jmp.L3 //跳转到L3

.L2:

movl$0, %eax //eax寄存器设为0

.L3:

movl%eax, -12(%ebp) //结果保存到变量c(下面是或运算的部分了)

cmpl$0, -4(%ebp)

jne.L4

cmpl$0, -8(%ebp)

je.L5

.L4: //a不为0则会走到这里

movl$1, %eax //设定eax为1

jmp.L6

.L5: //a、b均为0则会走到这里

movl$0, %eax //设定eax为0

.L6:

movl%eax, -16(%ebp) //结果保存到变量d

movl$0, %eax

leave

.cfi_restore 5

.cfi_def_cfa 4, 4

ret

.cfi_endproc

.LFE0:

.sizemain, .-main

.ident"GCC: (GNU) 4.6.1 20110908 (Red Hat 4.6.1-9)"

.section.note.GNU-stack,"",@progbits

从这个汇编代码中就体现了C语言逻辑运算的截断特性。即对于与操作,第一个0的出现表示整个合取式为0;对于或操作,第一个1的出现表示整个析取式为1。那么,当我们在写逻辑运算表达式的时候,如果可能的话,应当考虑每个项为真或为假的概率,例如,在一个合取式a && b当中,b为0的概率比a为0的概率大得多,那么我们用b && a来代替a && b是可以起到提高效率的作用的。

有些时候代码的优化工作会由编译器完成,不过,对于变量取值可能性的估计,编译器大多数情况是无法做到的,因此,在这种情况下,我们还是应该尽量人工完成这部分优化工作。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值