由strlen()引发的小问题(有符号无符号比较的汇编层次理解)

30 篇文章 0 订阅
21 篇文章 0 订阅

看到strlen的源码,很简单,检测‘\0’
下面为我的源码

#define NOP do{}while(0)
unsigned int mstrlen(const char * str)
{
    int length;
    for(length=0;*str!='\0';str++)
        length+=1;
    return length;
}

这里有个细节 就是返回值是无符号,在 pointers on c中讲到如果比较两个字符串长度会发生什么,看看下面先执行哪个NOP

if(mstrlen("ni")-mstrlen("nihao")>=0)
        NOP;
NOP;

实践为两个都执行,很好
判断的左边是无符号,右边是默认有符号,
在写个代码

    unsigned int uint =1;
    if(uint>-1)
        NOP;
    NOP;

实践,只执行最后一个NOP
再看看机器码级别的秘密,修改一下代码

    unsigned int ui =1;
    int i = -1;
    if(ui>-1)
        NOP;
    NOP;

在vs2008下反汇编得到的是

    unsigned int ui =1;
0137360F  mov         dword ptr [ui],1 
    int i = -1;
01373616  mov         dword ptr [i],0FFFFFFFFh 
    if(ui>-1)
0137361D  cmp         dword ptr [ui],0FFFFFFFFh 
01373621  jbe         main+97h (1373627h) 
        NOP;
01373623  xor         eax,eax 
01373625  jne         main+93h (1373623h) 
    NOP;
01373627  xor         eax,eax 
01373629  jne         main+97h (1373627h) 

在linux gcc下,利用objdump得到的是

这里写图片描述

gcc 直接优化了,直接没有比较,好叼。
在深入理解计算机系统书中也提到这个问题(第二版P53),
机器码是无所谓有符号无符号的,这些都是编译器的小动作

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值