最美情侣中文字幕电影,在线麻豆精品传媒,在线网站高清黄,久久黄色视频

歡迎光臨散文網(wǎng) 會(huì)員登陸 & 注冊

從匯編代碼中探究整數(shù)的除法運(yùn)算

2021-04-28 11:01 作者:剎那-Ksana-  | 我要投稿

前言

看過我的匯編語言101的人應(yīng)該都知道,指令div D或者idiv D是用于做除法的指令(具體的過程可以參考我的匯編語言101視頻)

例如:

是 n/5 的指令,運(yùn)算結(jié)果會(huì)儲存在eax中。

但是,以上的Assembly最多只會(huì)在-O0見到,如果把優(yōu)化等級調(diào)到最高的-O3,你基本上見不到div這個(gè)指令。

此外,我對電路設(shè)計(jì)不是很了解,如果你想要知道CPU是如何做除法運(yùn)算的,可以參考這里:https://electronics.stackexchange.com/questions/22410/how-does-division-occur-in-our-computers

*注意:本文之后所有數(shù)字,如果在末尾加b,則代表這是一個(gè)2進(jìn)制下的數(shù),否則就是十進(jìn)制下的數(shù)

一、n/1

我們先從最簡單的n/1開始,不用說,n/1那就是n,如果是-O0,編譯器會(huì)生產(chǎn)如下的匯編代碼

這就是沒有優(yōu)化前的代碼,我們說什么,編譯器做什么。如果是-O3的話,編譯器會(huì)直接返回n,即,直接忽略我們的除法運(yùn)算。

本文之后的內(nèi)容都以-O3為標(biāo)準(zhǔn),不在談及-O0

二、整數(shù)除以2的n次方

接下來是非負(fù)整數(shù)除以2,眾所周知,我們的計(jì)算機(jī)用bit shift做整數(shù)的除法運(yùn)算,比如說

這個(gè)正數(shù)的除法運(yùn)算對應(yīng)的assembly:

把所有bit往右移動(dòng)1的距離,比如1011b移動(dòng)后就變成了0101b,十進(jìn)制下的11就變成了5。

同樣的,如果我們要除以4,那么我們就把eax朝右移動(dòng)2位,除以8就移動(dòng)3位。

但是注意,如果我們bit位移量大于我們數(shù)據(jù)類型的長度的話,會(huì)出現(xiàn)什么呢?比如說,讓一個(gè)word類型的數(shù)據(jù)除以2的17次方,這個(gè)時(shí)候,我們的程序不會(huì)再進(jìn)行bit位移,而是直接返回0

xor自己本身就是將自己清零)

但是等等,這個(gè)并不是故事的全部,上面的是非負(fù)整數(shù),如果是整數(shù)的話,我們的代碼還會(huì)再多2行

我們在這里做得運(yùn)算,用公式寫出來就是

(n%2BnSHR31)SAR1

引入n SHR 31的作用顯而易見,就是n為負(fù)數(shù)的情況下——比如n=-2時(shí),bit右移31位后會(huì)獲得1b,然后二者相加得到-1,然后做bit右移1位同時(shí)sign填充后獲得-1;如果是在n為正數(shù)的情況下,n SHR 31這個(gè)數(shù)直接被忽略掉了。

三、整數(shù)除以整數(shù)

接下來我們來看一下整數(shù)與整數(shù)的除法運(yùn)算,我們先假定我們的兩個(gè)數(shù)都是非負(fù)數(shù),如一個(gè)非負(fù)整數(shù)n除以5,將會(huì)得到如下的匯編代碼:

我們還是沒有看見div的身影。上面的代碼稍微有點(diǎn)復(fù)雜,但是我們本質(zhì)上就是,將n的值乘以3435973837,然后bit右移34位(注意此處rax長度為64)

我們在這里可以隨便找一個(gè)數(shù)試一試,比如n=123:

123*3435973837%3D422624781951

1100010 01100110 01100110 01100110 01111111b

右移后我們得到11000b,即24;而123/5的結(jié)果則是24.6,去掉小數(shù)點(diǎn)我們得到24

我們試著把3435973837這個(gè)數(shù)字去除以2^34,我們會(huì)得到非常接近0.2的數(shù),準(zhǔn)確的說是0.2后面很多個(gè)0然后一個(gè)1。

我們現(xiàn)在取消我們非負(fù)數(shù)的限制,同樣的n/5我們會(huì)得到以下的代碼

因?yàn)樵谶@里我們涉及到正負(fù)號,所以我們有movsxsar兩個(gè)和符號有關(guān)的指令,并且最后一步我們居然是做一個(gè)減法運(yùn)算。用公式表達(dá)就是:

(%20n*1717986919%20SAR33%20)%20-%20(%20n%20SAR%2031%20)%20%20

我們可以理解為n*0.2然后減去一個(gè)非常小的數(shù) n SAR 31;為什么是這個(gè)組合,我不知道,但是nSAR31似曾相識?我們上面那一節(jié)里面貌似也有一個(gè)n?SHR?31?

以上就是3種不同情況下的除法(如果是浮點(diǎn)型數(shù)據(jù)的除法的話,我們不可避免地還是會(huì)用到divss這個(gè)指令)

下一篇文章我會(huì)再和大家來講講取余運(yùn)算,劇透一下,還是沒有div這個(gè)指令。

參考工具:Compiler Explorer: https://godbolt.org/

THE END.

從匯編代碼中探究整數(shù)的除法運(yùn)算的評論 (共 條)

分享到微博請遵守國家法律
松溪县| 绍兴市| 盐亭县| 巴林左旗| 三江| 宜川县| 清新县| 昌邑市| 巴彦县| 福海县| 芦山县| 安吉县| 喀什市| 徐闻县| 依兰县| 淮滨县| 霍林郭勒市| 南漳县| 饶阳县| 东方市| 凤城市| 贞丰县| 汪清县| 阳朔县| 霍州市| 雷州市| 长阳| 柘城县| 监利县| 台东县| 胶州市| 白朗县| 宣化县| 青阳县| 桂林市| 宁乡县| 永城市| 名山县| 康马县| 黄大仙区| 洮南市|