來寫個簡單的技術問題,也不要讓來部落格逛的一些工程師們失望。
之所以會有個議題是有人問版主關於 FPPA 多核心的旗標方式。
----
這個8051 的指令 DA 讓許多人搞得不是很清楚尤其是被8051 『荼毒』很久的人~
常常當他要轉別的 MCU 時會搞得受不了。
這個指令常是用來作 BCD (Binary coverter Decimal)運算用的。
像是一些時鐘、或轉速表的顯示啊!
誰叫我們人類是十根手指頭。電腦卻偏偏是二進位~卻又表示成 十六進位。
-----------------
首先我們把 DA A 這種8051 專有指令先丟一邊不管。
接下來就是介紹有名的旗標:AC ,一般稱為輔助進位旗標。(他也算是四位元時代留下的東西之一吧!)
再來看 AC 這個旗標的定義:他是當 Low Nibble 進位到High nibble 時,會舉一!
所以
mov a, 0x18
add a, 0x08 ; 0x18 +0x08 = 0x20 <---- 很明顯達到上述的條件。
所以,AC 這個旗標舉一是沒錯的。
------
我們再來研究所謂BCD的運算:
所謂BCD的運算是:
0d18 + 0d?? = 0d $$
他的運算來源Source1(0d18) 已經是10 進位的表示。
要加上某一個值~ 這個值也是用十進位表示的(0d??) !
當然結果也是要十進位啊 (0d$$) 這樣才算是十進位(BCD) 的運算。
所以,在程式(電腦)裡要判斷是否滿足十進位的進位條件時,
就必須:試加 0h06 來看 AC 旗標。來決定是否進位。
注意喔~因為您的運算的Source 已經是BCD 的表示了喔!(這是關鍵)
所以:
譬如 0d18 (當然,程式看起來是 0x18 ,其實他是BCD的十進位表示的!)
0d 18 + 0d01 = 0d19 ---> 這時就要拿add 0x06 來看AC旗標有沒有進位。
----> 沒有!所以答案是0d19 (仍然是BCD的十進位表示的!雖然程式裡看起來是0x19)
如果 0d18 + 0d04 ---> 0d1C, 我們再拿 add 0x06 來試AC旗標有沒有進位
----> 發現得一 !所以要進位。所以答案就是 0d22 (因為這裡的C值(12)要減去去10啊)
所以答案還是十進位的 0d22 沒錯!
好玩吧!....這是聰明的人類腦筋才會這麼複雜的數學系統之間的轉換。
然後,您也會發現:原來微控器裡的這些奇奇怪怪原來都是有他的定義與特殊用法的。
當然,您是用高階C在寫程式時,您就沒有這種探討人類智慧的機會。
---- 老天爺對所有人都是公平的~腦筋一定是越用越靈光的!如果,您要擺著不用也犯不了誰啊!
--------- 所謂靜思一得吧!
沒有留言:
張貼留言