Linux /Android ARM 64 bit/32 bit 编程移植

ARMv8 arch overview

32bit user @ 64 bit kernel

ARMv8支持64-bit 和32-bit所规范的层次结构


ARMv8arch overview-generalregister layout

Armv8架构下有31个通用寄存器(R0-R30),每个寄存器有64bit的位宽。访问方式:

      当作64-bit寄存器来访问,命名为(X0-X30)
      当作32-bit寄存器来访问,命名为(W0-W30)

      X30用来作为连接寄存器(LR), 用来保存调用子程序的返回地址或者异常返回地址.
     SP是专用堆栈指针寄存器,位宽64bit,用来保存当前处理器模式的堆栈的栈顶。
      PC是程序计数器,位宽64bit,其内容是处理器要取的下一条指令的地址。Armv8软件上不能直接操作PC。

ARMv8arch overview-AddressTranslation


l Usecompat_ioctl( ) but not onlyunlock_ioctl() in kernel driver
lcompat_ioctl( ) :支持64bitdriver必须要实现的ioctl当有32bituserspace application call 64bit kernelIOCTL的时候,这个callback会被调用到
lioctl参数和结构体一致性

 1.   数据类型
nILP32数据模型是32bit系统中用的最多的数据模型,在64bit系统中,用的比较多的就有两种LP64LLP64
nLP64主要用在linux系统上,而LLP64主要用在windows系统上,移植代码时需要注意数据类型在不同平台上的长度

Programming Type

ILP32

LP64(linux)

LLP64(windows)

char

8-bit

8-bit

8-bit

short

16-bit

16-bit

16-bit

int

32-bit

32-bit

32-bit

long

32-bit

64-bit

32-bit

long long

64-bit

64-bit

64-bit

float

32-bit

32-bit

32-bit

double

64-bit

64-bit

64-bit

size_t

32-bit

64-bit

64-bit

void * (pointer)

32-bit

64-bit

64-bit

intptr_t

32-bit

64-bit

64-bit

ptrdiff_t

32-bit

64-bit

64-bit


2.   类型转化


3.   高位截断

情形一:函数中如果需要精确地控制指针偏移时,有时候需要添加一个偏移量,处理时我们可能会选择先把指针转化为 int 或者 unsigned int 类型,这在 32bit 平台上是 OK 的,但在 64bit 平台上则会发生高位截断。强制类型转换会把高位数据丢 .

情形二:在分配一个对齐指针时,可能会先把指针做类型转化,接着再与上一个对齐量,这种做法在64bit平台上也同样存在高位截断问题。

4.移位有效性
   
32bit 平台允许 bitNum 设置在 0~31 之间,在 64bit 平台可能允许 bitNum 设置在 0~63 之间。
下边函数 SetBitN ( ) 32bit 平台上可以正常工作, 但在 64bit 平台,当 bitNum >31 时候,便取不到正确结果。这是因为对于没有加任何后缀的常量或者立即数,编译器会认为它属于最小的那种类型。

longlongSetBitN(longlong value, unsignedbitNum)

{

       longlong mask

       mask = (longlong) 1 <<bitNum;

       return value |msk;

}

或者

{

       longlong mask

       mask = 1LL<<bitNum;

       return value |mask;

}

5.位域操作
32bit平台下由于longint数据类型长度一样,可以取得正确的结果。


64bit平台下由于long int数据类型长度不一致,将会取得错误的结果。

6.函数返回
情形一:这种错误跟函数原型的定义有关系,例如在函数中引用一个子函数,而子函数没有显式定义的话,虽然链接的时候还是可以链接成功,但编译器由于不知道返回值是什么,就会使用缺省的int类型。
例如下边的例子,在 64bit 平台上就不能很好的工作了。


8.   常数有效性

情景一:有时候如果是习惯于32bit的思维,做一些操作时我们会去做一些假设,比如pointer size等于40x7FFF FFFF32bit有符号数最大值等等,或者在32bit环境下常用无符号常量0xFFFF FFFF用来测试是否等于-1

                defineINVALID_POINTER_VALUE 0xFFFFFFFF

64bit系统中,这个值不是-1, 而是4294967295; 在64bit系统中,-1正确的值应当为0xFFFF FFFFFFFFFFFF。要避免这个问题,在常量声明时,使用const并带上signed或者unsigned

                  Const signedintINVALID_POINTER_VALUE =  0xFFFF FFFF

上边代码,在32bit或者64bit环境下都可以正常运行。另外,根据需要,适当的使用L后缀或者U后缀来声明整形常量。


代码检查check list

声明

1)如果变量32bit平台是32位的,64bit平台是32位的,根据需要可以将其类型定义为int

2)如果变量32bit平台是32位的,64bit平台是64位的,根据需要可以将其类型定义为long

3)防止符号扩展,需要Check变量是否可以定义成unsigned.

4)防止符号扩展,需要Check常量是否需要添加L”或者U”来约束.

表达式

1Check表达式是否存在显示类型转换

2)注意隐形转化,需要Check表达式操作数是否混合使用不同数据类型.

3)注意隐形转化,需要Check表达式操作数是否混合使用有符号数与无符号数.

赋值

1Check是否存在把指针变量赋值给int

2Check是否存在把int赋值给指针变量

3Check是否存在左值&&右值数据类型不一致

函数参数相关

1Check调用到的函数,是否已经声明。

2Check实参数据类型与形参数据类型是否匹配。

字符串格式化

1Check地址打印,尽量使用printk("addr=%p\n", addr)格式.

2Check整型打印,例如int型用%d或者%xlong型用%ld或者%lx.

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值