Linux内核之32/64位除法
目录
- 前言
- 一、问题
- 二、解决方法
- 1.根本原因描述
- 2.解决方法
- 三、总结学习
- 1.do_div 函数
- 2.Linux 内核实现的64位除法函数
前言
本文主要是介绍 Linux 内核提供的关于32位与64位除法已经实现的接口,使得在 Linux 中需要除法运算或编译中遇到如上问题时能正确解决问题。
一、问题
在编译 Linux 代码时,经常会遇到如下错误:
undefined symbol ‘udivdi3’undefined symbol 'divid3'
二、解决方法
1.根本原因描述
在嵌入式中,32位系统中(目前多数系统都是,比如 ARM),对于普通的 a 除以 b(b 为32位):
(1)当 a 为32位,Linux 内核中,常用 uint32_t 类型,可以直接写为 a / b;
(2)但是,对于 a 是64位,uint64_t 的时候,就要用到专门的除操作相关的函数,linux 内核里面一般为 do_div(n, base),注意,此处do_div得到的结果是余数,而真正的 a / b 的结果,是用 a 来保存的。
do_div(n,base) 的具体定义,和当前体系结构有关,所以其具体实现在相关架构目录下的 <asm/div64.h>,其实现较为复杂,我也没看懂。
因此,如果你当前写代码,a / b,如果 a 是uint64_t类型,那么一定要利用do_div(a,b),而得到结果 a,
而不能简单的用 a / b,否则编译可以正常编译,但是最后链接最后出错,会提示上面的那个错误:
undefined reference to “__udivdi3”
2.解决方法
知道导致该错误的根本原因之后,就可以在代码中找到对应的用到除法
的地方
即类似于 a / b
的地方,其中被除数 a 为64位,Linux中一般用用 uint64_t
,将a / b
用 do_div(a,b)
得到的 a
去代替(注意,不是直接用 do_div() 得到真正 a 除 b 后的结果,因为 do_div(a, b) 得到的是余数)
三、总结学习
1.do_div 函数
#define do_div(n, base) __do_div_asm(n, base)#define __do_div_asm(n, base) [省略]
函数功能:
实现在32位处理器中实现64位除法,需要包含头文件 <asm/div64.h>可以将其实现理解为:ret = n % base;n /= base;
函数参数:
n: uint64_t 的被除数base: 32位的除数
函数返回值:
被除数除以除数的余数。
2.Linux 内核实现的64位除法函数
Linux 内核封装好了支持64位除法的函数,包含 unsigned 和 signed 两类,具体函数如下,需要包含头文件 < linux/math64.h >
#if BITS_PER_LONG == 32 //针对32位处理器
(1)div_u64
/* * unsigned 64位除法,不需要的得到余数* Param - u64 : 被除数* Param - u32 : 除数* Return - u64 : 除后的结果*/
static inline u64 div_u64(u64 dividend, u32 divisor)
{u32 remainder;return div_u64_rem(dividend, divisor, &remainder);
}/* * unsigned 64位除法,需要的得到余数* Param - u64 : 被除数* Param - u32 : 除数* Param - u32* : 除后的余数* Return - u64 : 除后的结果*/
static inline u64 div_u64_rem(u64 dividend, u32 divisor, u32 *remainder)
{*remainder = do_div(dividend, divisor);return dividend;
}
(2)div_s64
/* * signed 64位除法,不需要的得到余数* Param - s64 : 被除数* Param - s32 : 除数* Return - s64 : 除后的结果*/
static inline s64 div_s64(s64 dividend, s32 divisor)
{s32 remainder;return div_s64_rem(dividend, divisor, &remainder);
}/* * signed 64位除法,需要的得到余数* Param - s64 : 被除数* Param - s32 : 除数* Param - s32* : 除后的余数* Return - s64 : 除后的结果*/
s64 div_s64_rem(s64 dividend, s32 divisor, s32 *remainder)
{u64 quotient;if (dividend < 0) {quotient = div_u64_rem(-dividend, abs(divisor), (u32 *)remainder);*remainder = -*remainder;if (divisor > 0)quotient = -quotient;} else {quotient = div_u64_rem(dividend, abs(divisor), (u32 *)remainder);if (divisor < 0)quotient = -quotient;}return quotient;
}
EXPORT_SYMBOL(div_s64_rem);
Linux内核之32/64位除法相关推荐
- 如何查看Linux内核是否为64位版本?
方法非常简单,LINUX提供了一个查看配置的命令(实际有相应的库函数)getconf,使用它即可,方法如下: getconf LONG_BIT 如果返回64,就表示为64位内核,否则应当返回32. 本 ...
- linux内核高分辨率定时器,64位Linux上的高分辨率定时器支持
我试图在2.6.39.1 64位Linux上启用高分辨率定时器支持.为此,我首先在.config中设置CONFIG_HIGH_RES_TIMERS=y.64位Linux上的高分辨率定时器支持 而且,g ...
- 绿色无广告版装机工具:微PE工具箱Win8/10内核版32/64位
你需要好用的WinPE工具箱吗,快来下载微PE工具箱Win10版使用吧.所谓微pe就是完整的精简,现在已有了W10PE核心,使用它可以灵活地安装到系统开机启动项.制作可启动U盘.移动硬盘以及生成ISO ...
- linux驱动时间差引发的64位除法问题
推荐一个零声学院免费教程,个人觉得老师讲得不错, 分享给大家:[Linux,Nginx,ZeroMQ,MySQL,Redis, fastdfs,MongoDB,ZK,流媒体,CDN,P2P,K8S,D ...
- mp3 编辑 linux,Linux_Ubuntu 32/64位安装音乐标签编辑器Kid3的方法, Kid3能够修改mp3中ID3的tag标 - phpStudy...
Ubuntu 32/64位安装音乐标签编辑器Kid3的方法 Kid3能够修改mp3中ID3的tag标签,还能同时修改ID3v1和ID3v2的tag标签吗,是款功能强大的音乐标签编辑器,因为其在Ubun ...
- linux英伟达显卡驱动390下载,nvidia英伟达驱动|NVIDIA英伟达显卡驱动程序更新下载(32/64位) v384.90 Linux版 - 飞极下载站...
NVIDIA英伟达显卡驱动程序,支持32/64位Linux系统.除了常规的新上市游戏优化.VR支持.SLI支持.修复Bug以外,还有一个重磅更新,就是正式支持DirectX中间语言DirectX In ...
- Mac技巧之查看苹果电脑 Mac OS X 系统是否开启 64 位运算,以及设置 32/64 位模式的方法
Mac技巧之查看苹果电脑 Mac OS X 系统是否开启 64 位运算,以及设置 32/64 位模式的方法 引用功能被关闭了. 苹果电脑 Mac OS X 10.6 雪豹系统同时支持 32 位和 64 ...
- android 键编译,Android 音视频学习系列 (四) 一键编译 32/64 位 FFmpeg 4.2.2
前言 2020/5/20 增加了硬件解码编译脚本 编译环境 Centos + NDK20b + FFmpeg4.2.2 + Android-21/16 2020/4/26 更新了编译 64 位脚本 编 ...
- 网络浏览器 Vivaldi 32/64 位 v2.9.1705.31 中文便携版
Vivaldi 浏览器是由 Opera 前创始人兼 CEO 基于 Chromium / Blink 内核创立的新一代网络浏览器.它不仅界面简洁.速度极快,重点是可以原生兼容支持 Chrome 浏览器的 ...
最新文章
- python reshape transpose
- [Caffe]:关于*** Aborted at 1479432790 (unix time) try date -d @1479432790 错误的另一种原因
- html5拖动的面板 panel,基于jQuery UI的Bootstrap Panel面板功能增强插件
- Qt中视图的缩放对应缩略图中矩形框的缩放
- python实现编辑距离以及回溯路径
- NDK编译时指定NDK_MODULE_PATH的方法
- 如何将每日新闻添加到自己博客中,发送到微信群中
- 我为何在 CSDN 乐在其中
- GB28181平台对接接口详解
- PCB信号完整性及EMC整改措施
- 破解网络尖兵(真正对付限制ADSL路由共享的方法)
- 2023年,大型数据中心PUE将降到1.3以下...
- 注册表中修改桌面背景
- 诺基亚夏令营游学经历
- 地下城与勇士(DNF)寂静城副本(倒悬的瞭望台、卢克的聚光镜、钢铁之臂、能源熔炉、光之舞会、王的书库)
- android开发如何让子View的事件交给其上层父View去处理呢?
- Linux下的进程江湖
- python日记DAY1
- 班主任如何展开期中表彰班会
- 我爱天文 - 天文软件知多少?
热门文章
- 实验实例 —逻辑门设计
- Win10右键菜单“发送到”添加/删除选项的方法
- python中格式化输出的作用是什么_python格式化输出是什么意思
- 渭城曲 / 送元二使安西
- 计算机网络谢希仁第七版课后习题答案(第四章)
- 风电场气象服务器是什么系统,气象站资料在风电场前期工作中到底有多重要?...
- 思岚科技Athena打破机器人底盘价格极限
- 数据库 连接(自然连接,内连接,外连接)
- C语言fopen函数的用法,C语言打开文件详解
- 介绍几款可用的web应用防火墙