ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

一次int转换成unsigned long数值溢出问题

2022-04-17 19:03:41  阅读:161  来源: 互联网

标签:24 movl addq int unsigned long rbp eax


在项目中遇到一个奇怪的宕机问题,后来查询定位发现是erlang底层数据溢出问题,用c模拟情况类似,当一个int类型的x值大于等于1<<25的时候,再左移6位会造成nt溢出,然后再强转成64位无符号整数。

test_int.c

#include <stdio.h>

int main(){
    int a = 1;
    int x = (a<<25);
    int x1 = (x<<6)+10;
    unsigned long y = (unsigned long)(x1);
    y+=1;
    y+=1;
    y+=1;
    y+=1;
    printf("x=%d\n", x); 
    printf("x1=%d\n", x1);
    printf("y=%lu\n", y); 
    return 0;
}

输出结果

x=33554432
x1=-2147483638
y=18446744071562067982

gcc -S test_int.c

    subq    $32, %rsp
    movl    $1, -4(%rbp)      --- - -4(%rbp)表示a
    movl    -4(%rbp), %eax
    sall    $25, %eax
    movl    %eax, -8(%rbp) ----- -8(%rbp) 表示 x
    movl    -8(%rbp), %eax
    sall    $6, %eax
    addl    $10, %eax
    movl    %eax, -12(%rbp) ---- -12(%rbp) 表示x1
    movl    -12(%rbp), %eax ------ 这里开始符号扩展 
    cltq
    movq    %rax, -24(%rbp)
    addq    $1, -24(%rbp)
    addq    $1, -24(%rbp)
    addq    $1, -24(%rbp)
    addq    $1, -24(%rbp)
    movl    -8(%rbp), %eax
    movl    %eax, %esi

 

顺带再分析了一下32位有符号数转换成64位无符号数的时候在底层汇编会发生什么。

有符号数在底层都是用补码进行表示,转换成无符号数的时候需要根据最高位进行判断,最高位是1的话则用1来扩充,是0的话用0扩充。

cltq就是符号扩展指令,只对eax寄存器扩展到rax寄存器。
 


标签:24,movl,addq,int,unsigned,long,rbp,eax
来源: https://www.cnblogs.com/doudou1024/p/16156765.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有