5.2.1 移植过程演示
1.x86架构下运行效果
步骤1:登录x86架构服务器,进入/data/code/文件夹,创建文件transfer.c,指令如下:
cd /data/code/ vi transfer.c
步骤2:在文件transfer.c中输入如下代码:
这段代码按照预期,应该会打印出a=-1来。
步骤3:编译transfer.c,指令如下:
gcc -o transfer transfer.c
步骤4:执行transfer,查看输出结果,指令如下:
./transfer
输出结果如图5-5所示。
图5-5 x86架构输出结果
可以看出来,打印输出的结果就是希望看到的-1。
2.鲲鹏架构下运行效果
在鲲鹏架构下同样编译并执行。
步骤1:登录鲲鹏架构服务器,进入/data/code/文件夹,创建文件transfer.c,指令如下:
cd /data/code/ vi transfer.c
步骤2:在文件transfer.c中输入和x86架构下一样的代码,代码如下:
步骤3:编译transfer.c,指令如下:
aarch64 - redhat - Linux - gcc -o transfer transfer.c
步骤4:执行transfer,查看输出结果,指令如下:
./transfer
输出结果如图5-6所示。
图5-6 鲲鹏架构输出结果
这个结果和预期的结果不一样,输出的是255。
3.原因分析
-1的二进制原码是10000001,它的补码是除了符号外取反加1,最后补码就是11111111。在x86架构下,char默认是有符号的,所以打印的时候正常打印-1,但是在鲲鹏架构下char默认是无符号的,这个二进制的11111111正好就是无符号的255。
所以,出现这种情况的原因就是x86架构和鲲鹏架构对于char的默认处理不一样,一个是默认有符号,另一个是默认无符号。
4.处理方式
对于这种情况,有两种处理方式,一种是修改源代码,把数据类型指定为有符号型,另一种就是在编译时指定参数,把默认无符号型改成默认为有符号型,下面演示说明。
1)修改编译参数
修改编译参数比较简单,只需要在gcc后面加入-fsigned-char编译选项即可,命令如下:
aarch64 - redhat - Linux - gcc -fsigned-char -o transfer transfer.c
需要注意的是,该选项会把源代码中所有的char类型变量都当作有符号类型,如果只是更改其中部分char变量,这种方式就不合适了。
修改后的执行效果如图5-7所示,可以看到得到了期望的输出。
2)修改源代码
修改源代码虽然有点复杂,但灵活性比较高,可以一劳永逸地解决问题,修改方法就是把char类型改成signed char即可。在/data/code/目录下新建transfer_new.c,然后输入修改后的代码:
图5-7 鲲鹏架构修改编译参数后的输出结果
编译的时候不用指定编译选项,直接编译即可,最后执行效果如图5-8所示,可以看到也得到了期望的输出。
图5-8 鲲鹏架构下transfer_new执行输出结果