使用asm/div64.h中宏do_div

#include <asm/div64.h>
unsigned long long x,y,result;
unsigned long mod;
mod = do_div(x,y);
result = x;
64 bit division 结果保存在x中;余数保存在返回结果中。

【问题】

编译Linux下面的代码,经常会遇到这种错误:

undefined reference to `__udivdi3’

【解决过程】

之前遇到过几次了,都是类似的原因导致此问题的。后来才了解,其根本原因:

嵌入式中,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)的具体定义,和当前体系结构有关,对于arm平台,在

arch/arm/include\asm\div64.h

其实现很复杂,感兴趣的自己去代码里看吧,这里不多说了。

因此,如果你当前写代码,a/b,如果a是uint64_t类型,那么一定要利用do_div(a,b),而得到结果a,

而不能简单的用a/b,否则编译可以正常编译,但是最后链接最后出错,会提示上面的那个错误:

undefined reference to “__udivdi3”

【解决方法】

知道原因,就好办了。办法就是,去你代码里面找到对应的用到除法的地方,即类似于a/b的地方,其中被除数a为64位,Linux中一般用用 uint64_t,将a/b用do_div(a,b)得到的a去代替(注意,不是直接用do_div()得到真正a除b后的结果,因为 do_div(a,b)得到的是余数,囧。。。),即可,而具体写其他,就显得很麻烦。此处,我们可以借鉴Linux中\fs\yaffs2 \yaffs_fs.c中的宏:

static uint32_t YCALCBLOCKS(uint64_t partition_size, uint32_t block_size)
{
uint64_t result = partition_size;
do_div(result, block_size);
return (uint32_t)result;
}

来自己也去封装一个支持64位数的除法的函数,不过,Linux内核就是好,早已经帮我们实现了对应的64位的unsingned和signed两个函数:

static inline u64 div_u64(u64 dividend, u32 divisor);

static inline s64 div_s64(s64 dividend, s32 divisor);
我们可以直接拿过来用了,注意用此函数时,要包含对应头文件:

#include <linux/math64.h>

总结一下就是:

1.先包含头文件:

2.然后用(a,b)得到a/b的结果即可。

【提示】

如果需要在进行64位除数的时候,同时得到余数remainder,可以直接用

static inline u64 div_u64_rem(u64 dividend, u32 divisor, u32 *remainder);
static inline s64 div_s64_rem(s64 dividend, s32 divisor, s32 *remainder);

【引用】

64 bit division in linux

If you’ve encountered an error message like this

Unknown symbol __udivdi3Unknown symbol __umoddi3Unresolved symbol __udivdi3Unresolved symbol __umoddi3
you most likely want to make a 64 bit division, which is not supported by default in linux kernel space.
To solve this problem, you need to use the do_div macro available in asm/div64.h:

#include <asm/div64.h>unsigned long long x, y, result;unsigned long mod;mod = do_div(x, y);result = x;
If you want to calculate x / y with do_div(x, y), the result of the division is in x, the remainder is returned from the do_div function.
Since do_div is just an asm (assembler) macro, it doesn’t break real time determinism, so it’s also suitable for use in RTAI classic, RTAI fusion and ADEOS/ADEOS-IPIPE applications.

Linux内核中64位除法函数do_div相关推荐

  1. linux内核启用64位除法,关于内核中的乘法和除法。

    关于内核中的乘法和除法. 作者:heziq 发布于:2015-5-6 22:02 前几天一直在看wowo的时间子系统,一直在思索mult和shift变量,为什么mult要尽量大,shift尽量小.这是 ...

  2. Linux内核中常见内存分配函数

    1.      原理说明 Linux内核中采用了一种同时适用于32位和64位系统的内存分页模型,对于32位系统来说,两级页表足够用了,而在x86_64系统中,用到了四级页表,如图2-1所示.四级页表分 ...

  3. linux内核中send与recv函数详解

    Linux send与recv函数详解 1.简介 #include <sys/socket.h> ssize_t recv(int sockfd, void *buff, size_t n ...

  4. linux内核时间函数us,linux内核中一个有趣的函数calibrate_delay ZZ

    该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 34  loops_per_sec &=~loopbit; 35  } 36 /* finally,adjust loops per second ...

  5. 华硕 固件 Linux内核,ubuntu 64位编译华硕AC1200G+固件

    Ubuntu版本16.04 1.安装依赖包 sudo apt-get install --no-install-recommends  autoconf automake bash bison bzi ...

  6. Linux内核之32/64位除法

    目录 前言 一.问题 二.解决方法 1.根本原因描述 2.解决方法 三.总结学习 1.do_div 函数 2.Linux 内核实现的64位除法函数 前言 本文主要是介绍 Linux 内核提供的关于32 ...

  7. linux 内核flush,armv8(aarch64)linux内核中flush_dcache_all函数详细分析

    /* *  __flush_dcache_all() *  Flush the wholeD-cache. * Corrupted registers: x0-x7, x9-x11 */ ENTRY( ...

  8. 大话Linux内核中锁机制之原子操作、自旋锁【转】

    转自:http://blog.sina.com.cn/s/blog_6d7fa49b01014q7p.html 多人会问这样的问题,Linux内核中提供了各式各样的同步锁机制到底有何作用?追根到底其实 ...

  9. Linux 内核中的数据结构:双链表,基数树,位图

    Linux 内核中的数据结构 rtoax 2021年3月 1. 双向链表 Linux 内核自己实现了双向链表,可以在 include/linux/list.h 找到定义.我们将会从双向链表数据结构开始 ...

最新文章

  1. C++11中unique_ptr的使用
  2. java.lang.OutOfMemoryError: Java heap space的解决办法
  3. .Net Framework 各个版本新特性总结 (一)
  4. Chtml的一些例子
  5. MATLAB调用python文件方法
  6. oracle into多个变量,Oracle中merge into的使用:该命令使用一条语句从一个或者多个数据源中完成对表的更新和插入数据....
  7. servlet解决javascript传来中文乱码问题
  8. 利用队列实现车厢编组
  9. C# 创建一个简单的WebApi项目
  10. solr 高亮springdatasolr
  11. python上下文管理协议_Python3基础-上下文管理协议
  12. 帮你排雷Jmeter分布式性能测试那些坑~轻轻松松去实战
  13. 电子计算机入门教程,「冯修远」计算机入门0基础教程:Word文档的基本操作
  14. 张一鸣在字节跳动7周年庆典上的演讲
  15. 金融行业的JAVA软件开发
  16. 有趣且重要的Git知识合集(5)Merge branch ‘master‘ of
  17. UML之独孤九剑总纲
  18. 合唱队——最少出列人数
  19. Excel关闭受保护的视图
  20. 小菜鸟之JAVA面试题库1

热门文章

  1. 高校公房管理的重要性与管理范围
  2. windows的139端口和445端口的区别
  3. 计算机等级考试一般在什么时候?
  4. Sliding bottom tab 仿 bilibili 安卓客户端滑动 tab
  5. lua语言入门学习(一)搭建基本的环境并实现运行
  6. 网易游戏虚拟世界架构师面试经验
  7. Android setbackgroundcolor()方法的使用
  8. 如何制作CSR文件?
  9. OpenWrt make menuconfig 构建过程
  10. 史上最牛的五次黑客攻击