目录

  • 前言
  • 一、问题
  • 二、解决方法
    • 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 / bdo_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位除法相关推荐

  1. 如何查看Linux内核是否为64位版本?

    方法非常简单,LINUX提供了一个查看配置的命令(实际有相应的库函数)getconf,使用它即可,方法如下: getconf LONG_BIT 如果返回64,就表示为64位内核,否则应当返回32. 本 ...

  2. linux内核高分辨率定时器,64位Linux上的高分辨率定时器支持

    我试图在2.6.39.1 64位Linux上启用高分辨率定时器支持.为此,我首先在.config中设置CONFIG_HIGH_RES_TIMERS=y.64位Linux上的高分辨率定时器支持 而且,g ...

  3. 绿色无广告版装机工具:微PE工具箱Win8/10内核版32/64位

    你需要好用的WinPE工具箱吗,快来下载微PE工具箱Win10版使用吧.所谓微pe就是完整的精简,现在已有了W10PE核心,使用它可以灵活地安装到系统开机启动项.制作可启动U盘.移动硬盘以及生成ISO ...

  4. linux驱动时间差引发的64位除法问题

    推荐一个零声学院免费教程,个人觉得老师讲得不错, 分享给大家:[Linux,Nginx,ZeroMQ,MySQL,Redis, fastdfs,MongoDB,ZK,流媒体,CDN,P2P,K8S,D ...

  5. mp3 编辑 linux,Linux_Ubuntu 32/64位安装音乐标签编辑器Kid3的方法,  Kid3能够修改mp3中ID3的tag标 - phpStudy...

    Ubuntu 32/64位安装音乐标签编辑器Kid3的方法 Kid3能够修改mp3中ID3的tag标签,还能同时修改ID3v1和ID3v2的tag标签吗,是款功能强大的音乐标签编辑器,因为其在Ubun ...

  6. linux英伟达显卡驱动390下载,nvidia英伟达驱动|NVIDIA英伟达显卡驱动程序更新下载(32/64位) v384.90 Linux版 - 飞极下载站...

    NVIDIA英伟达显卡驱动程序,支持32/64位Linux系统.除了常规的新上市游戏优化.VR支持.SLI支持.修复Bug以外,还有一个重磅更新,就是正式支持DirectX中间语言DirectX In ...

  7. Mac技巧之查看苹果电脑 Mac OS X 系统是否开启 64 位运算,以及设置 32/64 位模式的方法

    Mac技巧之查看苹果电脑 Mac OS X 系统是否开启 64 位运算,以及设置 32/64 位模式的方法 引用功能被关闭了. 苹果电脑 Mac OS X 10.6 雪豹系统同时支持 32 位和 64 ...

  8. android 键编译,Android 音视频学习系列 (四) 一键编译 32/64 位 FFmpeg 4.2.2

    前言 2020/5/20 增加了硬件解码编译脚本 编译环境 Centos + NDK20b + FFmpeg4.2.2 + Android-21/16 2020/4/26 更新了编译 64 位脚本 编 ...

  9. 网络浏览器 Vivaldi 32/64 位 v2.9.1705.31 中文便携版

    Vivaldi 浏览器是由 Opera 前创始人兼 CEO 基于 Chromium / Blink 内核创立的新一代网络浏览器.它不仅界面简洁.速度极快,重点是可以原生兼容支持 Chrome 浏览器的 ...

最新文章

  1. python reshape transpose
  2. [Caffe]:关于*** Aborted at 1479432790 (unix time) try date -d @1479432790 错误的另一种原因
  3. html5拖动的面板 panel,基于jQuery UI的Bootstrap Panel面板功能增强插件
  4. Qt中视图的缩放对应缩略图中矩形框的缩放
  5. python实现编辑距离以及回溯路径
  6. NDK编译时指定NDK_MODULE_PATH的方法
  7. 如何将每日新闻添加到自己博客中,发送到微信群中
  8. 我为何在 CSDN 乐在其中
  9. GB28181平台对接接口详解
  10. PCB信号完整性及EMC整改措施
  11. 破解网络尖兵(真正对付限制ADSL路由共享的方法)
  12. 2023年,大型数据中心PUE将降到1.3以下...
  13. 注册表中修改桌面背景
  14. 诺基亚夏令营游学经历
  15. 地下城与勇士(DNF)寂静城副本(倒悬的瞭望台、卢克的聚光镜、钢铁之臂、能源熔炉、光之舞会、王的书库)
  16. android开发如何让子View的事件交给其上层父View去处理呢?
  17. Linux下的进程江湖
  18. python日记DAY1
  19. 班主任如何展开期中表彰班会
  20. 我爱天文 - 天文软件知多少?

热门文章

  1. 实验实例 —逻辑门设计
  2. Win10右键菜单“发送到”添加/删除选项的方法
  3. python中格式化输出的作用是什么_python格式化输出是什么意思
  4. 渭城曲 / 送元二使安西
  5. 计算机网络谢希仁第七版课后习题答案(第四章)
  6. 风电场气象服务器是什么系统,气象站资料在风电场前期工作中到底有多重要?...
  7. 思岚科技Athena打破机器人底盘价格极限
  8. 数据库 连接(自然连接,内连接,外连接)
  9. C语言fopen函数的用法,C语言打开文件详解
  10. 介绍几款可用的web应用防火墙