2007年3月29日 星期四

8051 的DA指令

來寫個簡單的技術問題,也不要讓來部落格逛的一些工程師們失望。

之所以會有個議題是有人問版主關於 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在寫程式時,您就沒有這種探討人類智慧的機會。

---- 老天爺對所有人都是公平的~腦筋一定是越用越靈光的!如果,您要擺著不用也犯不了誰啊!

--------- 所謂靜思一得吧!

 

沒有留言:

張貼留言