鲲鹏架构入门与实战
上QQ阅读APP看书,第一时间看更新

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执行输出结果