免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 3947 | 回复: 6
打印 上一主题 下一主题

[C] 请教int和uint编译出来的代码究竟有什么不同 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2009-01-13 22:58 |只看该作者 |倒序浏览
10可用积分
想测试一下int和unit类型的整数,编译出来的汇编代码到底有什么不同:
[zhang@localhost kg]$ cat i.c
int main(){
   int i=4;
   unsigned j=8;
   int k=i+j;
   unsigned int l=i+j;
   return 0;
}
[zhang@localhost kg]$ gcc -S i.c
[zhang@localhost kg]$ cat i.s
        .file   "i.c"
        .text
.globl main
        .type   main, @function
main:
        leal    4(%esp), %ecx
        andl    $-16, %esp
        pushl   -4(%ecx)
        pushl   %ebp
        movl    %esp, %ebp
        pushl   %ecx
        subl    $32, %esp
        movl    $4, -24(%ebp)
        movl    $8, -20(%ebp)
        movl    -24(%ebp), %eax
        movl    %eax, -16(%ebp)
        movl    -20(%ebp), %eax
        movl    %eax, -12(%ebp)
        movl    -24(%ebp), %eax
        addl    -20(%ebp), %eax
        movl    %eax, -8(%ebp)
        movl    $0, %eax
        addl    $32, %esp
        popl    %ecx
        popl    %ebp
        leal    -4(%ecx), %esp
        ret
        .size   main, .-main
        .ident  "GCC: (GNU) 4.1.2 20071124 (Red Hat 4.1.2-42)"
        .section        .note.GNU-stack,"",@progbits

--------------------------------------------------
似乎没看出来int和uint有什么处理上的不一样啊,dx能解释一下产生的汇编代码有没有反应出什么区别吗?

10分感谢!

最佳答案

查看完整内容

说了那么多,才觉得被你绕进去了。看有符号运算与无符号运算的差别,不需要把转换扯进来。这是两个不同的问题,放在一起只会把人搞晕。下面的代码能看出不同:加、减、乘的运算是没有不同的。在你那里都是 mod 2^32 的运算,符号仅取决与你如何理解这些数。但除法无法合理地对应到环运算中,所以需要特殊处理。[ 本帖最后由 win_hate 于 2009-1-14 08:56 编辑 ]

论坛徽章:
0
2 [报告]
发表于 2009-01-13 22:58 |只看该作者
说了那么多,才觉得被你绕进去了。看有符号运算与无符号运算的差别,不需要把转换扯进来。这是两个不同的问题,放在一起只会把人搞晕。

下面的代码能看出不同:


  1. int main(){
  2.         int i,j,k;
  3.         unsigned int ui, uj, uk;
  4.         k=i/j;
  5.         uk=ui/uk;

  6.    return 0;
  7. }
复制代码


  1.         .file        "1.c"
  2.         .text
  3. .globl main
  4.         .type        main, @function
  5. main:
  6. .LFB2:
  7.         pushq        %rbp
  8. .LCFI0:
  9.         movq        %rsp, %rbp
  10. .LCFI1:
  11.         movl        -4(%rbp), %edx
  12.         movl        %edx, %eax
  13.         sarl        $31, %edx
  14.         idivl        -8(%rbp)                 ;; <---
  15.         movl        %eax, -12(%rbp)
  16.         movl        -16(%rbp), %eax
  17.         movl        $0, %edx
  18.         divl        -24(%rbp)                ;; <---
  19.         movl        %eax, -24(%rbp)
  20.         movl        $0, %eax
  21.         leave
  22.         ret
  23. .LFE2:
  24.         .size        main, .-main
  25.         .section        .eh_frame,"a",@progbits
  26. .......
复制代码


加、减、乘的运算是没有不同的。在你那里都是 mod 2^32 的运算,符号仅取决与你如何理解这些数。但除法无法合理地对应到环运算中,所以需要特殊处理。

[ 本帖最后由 win_hate 于 2009-1-14 08:56 编辑 ]

论坛徽章:
3
戌狗
日期:2014-09-10 17:07:162015年辞旧岁徽章
日期:2015-03-03 16:54:15wusuopu
日期:2016-06-17 17:43:45
3 [报告]
发表于 2009-01-14 04:00 |只看该作者
例子里好像没什么不同

论坛徽章:
0
4 [报告]
发表于 2009-01-14 08:38 |只看该作者
i+j 在运算前被类型提升为相同类型,转换规则相当复杂,但这里是转换为无符号整数(参考下面提到的 table 6-6)。具体表示是否改变,取决于机器和实现。在你的机器上,具体表示没有不同。然后赋值时,右边类型转换成左边的。但对于整数类型到整数类型的赋值,这个转换仍然是概念上的,具体表示不变。由于具体表示没有发生改变,代码当然也就没有不同了。

因为在你这里,int 和 unsigned int 都是 32 位。正负取决于你如何理解这些比特。比如 32 个 1 在无符号时被理解成 2^32-1,有符号时被理解成 -1。


《C A Reference Manual》

p189

6.2.1 Representation Changes
...
However, when a value of type int is converet to type unsigned int, a representation change may not be necessary.
...
p195
6.3.2 The Assignment Conversions
In a simple assignment expression, the types of the expressions on the left and right sides of the assignment operator should be the same. If they are not, an attempt will be made to convert the value on the right side of the assignment to the type on the left side.

......

p198
6.3.4 The Usual Binary Conversions

When two values must be operated on in combination, they are first converted according to the usual binary conversions to a single common type, which is also typically the type of the result. .....

An operator that performs the usual binary conversions on its two operands will first perform the usual unary conversions on each of the operands independently to widen short values and ....

Table 6-6 中有二元运算转换规则,里头说:

any other type + a signed type of less or equal rank = the unsigned type.

[ 本帖最后由 win_hate 于 2009-1-14 08:43 编辑 ]

论坛徽章:
0
5 [报告]
发表于 2009-01-14 09:25 |只看该作者
原帖由 win_hate 于 2009-1-14 08:38 发表
i+j 在运算前被类型提升为相同类型,转换规则相当复杂,但这里是转换为无符号整数(参考下面提到的 table 6-6)。具体表示是否改变,取决于机器和实现。在你的机器上,具体表示没有不同。然后赋值时,右边类型转 ...


比如:
int main()
{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;int i =  0;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;int j = -1;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;int k = i > j;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return 0 ;
}

汇编代码如下:
00401315&nbsp;&nbsp;&nbsp;&nbsp;call   0x4013d0 <__main>
0040131A&nbsp;&nbsp;&nbsp;&nbsp;movl   $0x0,-0x4(%ebp)
00401321&nbsp;&nbsp;&nbsp;&nbsp;movl   $0xffffffff,-0x8(%ebp)
00401328&nbsp;&nbsp;&nbsp;&nbsp;mov    -0x4(%ebp),%eax
0040132B&nbsp;&nbsp;&nbsp;&nbsp;cmp    -0x8(%ebp),%eax
0040132E&nbsp;&nbsp;&nbsp;&nbsp;setg   %al


int main()
{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;unsigned int i =  0;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;int j = -1;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;int k = i > j;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return 0 ;
}

汇编代码:
00401315&nbsp;&nbsp;&nbsp;&nbsp;call   0x4013d0 <__main>
0040131A&nbsp;&nbsp;&nbsp;&nbsp;movl   $0x0,-0x4(%ebp)
00401321&nbsp;&nbsp;&nbsp;&nbsp;movl   $0xffffffff,-0x8(%ebp)
00401328&nbsp;&nbsp;&nbsp;&nbsp;mov    -0x8(%ebp),%eax
0040132B&nbsp;&nbsp;&nbsp;&nbsp;cmp    -0x4(%ebp),%eax
0040132E&nbsp;&nbsp;&nbsp;&nbsp;setb   %al


在编译出来的代码中,对-1有个type promotion,这些代码会将-1的bit pattern解释为unsigned int。loader载入之后0就是0,而-1是0xFFFFFFFF,这个没变,但目标代码对其所表示的意义改变了(bit pattern)。一句话:数据没变,bit pattern变了。
因此,确切地说,应该是对-1的解释方式变了,而不是-1这个数变了。解释方式的改变体现在setg和setb的区别。

论坛徽章:
0
6 [报告]
发表于 2009-01-14 12:40 |只看该作者
不错,学习了
以前只知道应该会在一些指令上体现有符号无符号的差别,但是具体的倒没仔细想过
对at&t格式的汇编不熟悉,有好的入门教程推荐吗

论坛徽章:
0
7 [报告]
发表于 2009-01-14 22:45 |只看该作者
原帖由 win_hate 于 2009-1-14 08:46 发表
说了那么多,才觉得被你绕进去了。看有符号运算与无符号运算的差别,不需要把转换扯进来。这是两个不同的问题,放在一起只会把人搞晕。

下面的代码能看出不同:


int main(){
        int i,j,k;
     ...

太强大了,给分!
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP