1. 程式人生 > >核心函式 do_div() 與 undefined reference to __udivdi3

核心函式 do_div() 與 undefined reference to __udivdi3

本文來自:http://hi.baidu.com/serial_story/blog/item/8ff17654ecae9e58574e0018.html

【問題】

編譯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);

【引用】

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.


相關推薦

核心函式 do_div() undefined reference to __udivdi3

本文來自:http://hi.baidu.com/serial_story/blog/item/8ff17654ecae9e58574e0018.html 【問題】 編譯Linux下面的程式碼,經常會遇到這種錯誤: undefined reference to `__ud

undefined reference to gcc編譯器細節的關係

在用c語言寫專案的時候,有三個檔案,一個頭檔案兩個原始檔分檔案1檔案2,在編譯的時候,出現瞭如下的錯誤 經過檢查,在標頭檔案中的函式聲名沒有錯誤,在原始檔1中的函式定義也沒有錯誤,在原始檔2中的函式呼叫也沒有出現錯誤, 從此開始在網上查閱各種資料,都沒有得到滿意的答覆,然後問了一遍大佬

C++順序表應用3:元素位置互換之移位演算法(好好看著函式名!!)要不然就會 undefined reference to `build_table(Table&, int, int)'

順序表應用3:元素位置互換之移位演算法 Time Limit: 1000 ms Memory Limit: 570 KiB Problem Description 一個長度為len(1<=len<=1000000)的順序表,資料元素的型別為整型,將該表分

linux下生產者消費者問題程式碼,以及編譯c程式碼時error:undefined reference to sem_wait 解決方法之一

//本文的詳細講解內容請大家下載word文件:http://download.csdn.net/detail/chenqiai0/4611801 #include <stdio.h> #include <pthread.h>//執行緒 #includ

undefined reference to `__gnu_mcount_nc'的解決 在編譯核心時出現瞭如下錯誤:

在編譯核心時出現瞭如下錯誤: init/built-in.o: In function `do_one_initcall': calibrate.c:(.text+0x14): undefined reference to `__gnu_mcount_nc' init/built-in.o: In

c++ template 多層繼承下找不到純虛擬函式實現 報錯:undefined reference to "xxx"

如下程式碼中,定義了3個類,ClassA,ClassB,ClassC,依次為被繼承關係,ClassA,ClassB是模板類, 在ClassA中定義了一個純虛擬函式getKeyFromObject,實現將從V中獲取K的功能: getKeyFromObject函

CC++混合程式設計問題:.C++呼叫.C檔案時出現:undefined reference to `xxxxx()'

本人使用qt的介面和opengl功能模擬演算法,該演算法需要在嵌入式中執行,因此需要用純C編寫,此時涉及到在C++寫的qt介面檔案中呼叫C檔案的庫函式,原先以為只需在C++中把C的.h檔案包含進去就可以正常使用,後來發現,使用這種方法時,在程式碼編寫時,C++檔案裡可以直接連

關於 inline 函式的分析: *** undefined reference to ***

如果將函式的實現放在標頭檔案中,那麼每一個包含該標頭檔案的cpp檔案都將得到一份關於該函式的定義,那麼連結器會報函式重定義錯誤。 如果將函式的實現放在標頭檔案,並且標記為 inline 那麼每一個包含該標頭檔案的cpp檔案都將得到一份關於該函式的定義,並且連結

linux下開發,解決cocos2d-x中編譯出現的一個小問題, undefined reference to symbol &#39;pthread_create@@GLIBC_2.2.5&#39;

water span x86 code bject data- ace 技術分享 inux 解決cocos2d-x中編譯出現的一個小問題 對於cocos2d-x 2.×中編譯中,若頭文件裏引入了#include "cocos-ext.h",在進行C++編譯的時候會遇到例

[ c++] cmake 編譯時 undefined reference to `std::cout' 錯誤的解決方案

bin cut () cmake fin epo linking com urn cmake .. 和 make 之後,出現如下錯誤 Linking CXX executable ../../../bin/ModuleTest CMakeFiles/Modu

Linux下運行《UNIX環境高級編程》undefined reference to `err_quit 編譯出錯的處理方法

reg init def bre linux tput linux下 pan termios 錯誤信息: : undefined reference to `err_quit‘: undefined reference to `err_sys‘ 解決方法: 因為err

caffe日常坑系列之:undefined reference to symbol '_ZN2cv6String10deallocateEv'

iss ren and tor ssi symbols str mis locate 在使用caffe庫編譯C++時出現的 解決如下: /usr/bin/ld: /tmp/ccA5JGRP.o: undefined reference to symbol ‘_ZN2cv

求助codeblocks高手,解決undefined reference to問題

inf ren blank pic 解決 deb i94 weibo lan F44M73褂壓臼7MCAhttp://www.docin.com/sina_6370744687 2萍ZL5乃l7凍V徽3http://docstore.docin.com/uht219 1

安卓ndk 忽略 error: undefined reference to '找不到符號

armeabi 找不到 main cmak eset nat reference dto 原來 最近在搞天使之翼的mrp模擬器。。。 移到AndroidStudio了,現在想把原來的Android .mk那種方式的改成cmake的方式編譯,但是編譯時有一些符號找不到

undefined reference to `recvIpcMsg(int, ipc_msg*)'——#ifdef __cplusplus extern "C" { #endif

使用 type -s endif 但是 pcm nbsp rec c語言 最近在弄一個進程間通信,原始測試demon用c語言寫的,經過測試ok,然後把接口封裝起來了一個send,一個recv。 使用的時候send端是在一個c語言寫的http服務端使用,編譯ok沒有報錯,但是

undefined reference to symbol '_ZNK11GenICam_3_016GenericException17GetSourceFileNameEv'

specific nor pac lba stat rom weight sed i386 今天在編譯DALSA二次開發的源碼時,出現了如下錯誤: /usr/bin/ld: ./out/camera.o: undefined reference to symbol ‘_ZN

.build_release/lib/libcaffe.so: undefined reference to `cv::VideoCapture::set(int, double)'

writer undefined anaconda ons vid eset fig undefine caf CXX/LD -o .build_release/tools/convert_imageset.bin.build_release/lib/libcaffe.so

minigui:解決gvfb編譯報錯undefined reference to symbol 'XkbGetIndicatorState'

minigui在linux PC平臺建立開發環境時,需要Virtual Frame Buffer 支援(gvfb,qvfb),minigui官網提供了這兩個程式的原始碼,需要自己下載編譯並安裝到自己的PC上。 我用的是gvfb,minigui下載地址:http://www.minig

ffmpeg:libavformat/http.c:1435: error: undefined reference to 'inflateEnd'

安卓動態庫編譯過程中遇到了一個ffmpeg相關的報錯,具體資訊如下: libavformat/http.c:1435: error: undefined reference to 'inflateEnd' libavformat/http.c:626: error: undefined re

ffmpeg:libavfilter/vf_elbg.c:169: error: undefined reference to 'avpriv_init_elbg'

ffmpeg編譯過程中遇到的一個報錯,具體資訊如下: -e [info] [*] link ffmpeg -------------------- libavfilter/vf_elbg.c:169: error: undefined reference to 'avpriv_init_el