contribured by <
Ting199708 >
考慮以下 C 程式的 align4 巨集的作用是,針對 4-byte alignment,找到給定地址的 round up alignment address。
了解題目後我先將p=0x1997代入觀察
且依題意,p=0x1995, 0x1996, 0x1997, 0x1998,align§均等於0x1998,將其轉換為二進位觀察,分析如下:
經過二進位觀察後,發現最後4 bit需在加上數值K後變成10xx
所以,K=3,答案為(g)
Survey Linux Kernel Document後,我找到了以下function有用到aligment的概念
核心文件對此function解釋如下:
Some devices are naturally misaligned to compensate for things like the legacy DOS partition table 63-sector offset. Low-level drivers should call this function for devices whose first sector is not naturally aligned.
程式原始碼(/block/blk-setting.c, line 375):
應用範圍(/drivers/scsi/sd.c, line 2333):
由此可見,blk_quene_alignment_offset可根據使用的情況來對request_quene的offset進行alignment。
考慮以下C程式碼:
可改寫為以下等價程式碼:
首先我看到了原始C程式碼我對於將unsigned int x做&&運算有點疑問,因此我實際實驗了一次。
再來我將X=0~8代入程式進行分析,結果如下
由此可知,當x=0時func輸出為false,x!=0時,因為x在&&運算時視為True,所以func(x)結果為:
x==(x & (~x + 1)),即x=2的次冪時,結果為True
再來,分析下方等價程式碼,x=0時,其輸出為False,x!=0時,則需檢測x內所含的1的數量
因此,透過Z=0001和x做&運算,再將x向右移1 bit,即可計算x內1的bit數,若僅有1個"1",則unknow=1,回傳True;反之,若"1"的數量大於1個,則unknow=2,跳出迴圈,回傳False。
故,此題解答為(e) 1
透過bitwise運算計算兩數字中的最大或最小值
假設(x,y)=(14,24) and (24,14)
可見此程式的關鍵為透過(x-y)再右移31 bits,取得sing bit來達成判斷其大小的目的
分析程式,並考慮abs(-2147483648)所得到的結果
二補數是一種用二進位表示有號數的方法,以下用一簡單範例來說明
由上方範例可發現,只要將24的每個bit反向再加一,即可得到其負數(-24) 的二進位表示
首先先來分析此程式如何運作,由於電腦在儲存負數時是以二補數方式表示,因此,abs程式只要將負數再做一次二補數運算即可得到abs運算後的數值。
經過實際測試,abs(-2147483648)的輸出結果為-2147483648,很明顯的,此程式對於輸入的數字有所限制。
實際執行程式碼發現輸出數值錯誤:
實驗結果:
Please input the x: -2147483648
abs(-2147483648) = -2147483648
文字訊息不要用圖片來展現
分析程式原始碼,發現int32_t在儲存有號整數時,其範圍為-2147483647~2147483647,因此-2147483648儲存進去時會發生overflow的現象導致數值不正確
當 x=-2147483647及 x=2147483647時,程式均可正常運作,可見上述分析正確:
實驗結果:
Please input the x: -2147483647
abs(-2147483647) = 2147483647
實驗結果:
Please input the x: 2147483647
abs(-2147483647) = 2147483647
文字訊息不要用圖片來展現
因此,若要解決此問題,可將程式修改如下:
執行結果:
實驗結果:
Please input the x: -2147483648
abs(-2147483648) = 2147483648
當然,將此程式修改後X仍有限制,其範圍為 ~ ,不過對大多數情況皆已可適用。
避免引用中文 Wikipedia 詞目,因為後者可能會跟英文詞目內容不同步