找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 4484|回復(fù): 20
打印 上一主題 下一主題
收起左側(cè)

匯編之從單片機(jī)設(shè)計者的角度來學(xué)習(xí)單片機(jī)

  [復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
ID:266429 發(fā)表于 2019-10-24 21:34 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式

先說某一組端口接一排8LED燈的情況,如何做到讓這八個燈想亮哪個就亮哪個,想不亮哪個就不亮哪個。

比如說,8個燈,全部負(fù)極接地電位,正極接P18個端口,則此種情況下,如果要某個燈亮,則對應(yīng)的那一個單片機(jī)的端口就應(yīng)該為高電位,照此推算下來,如果要讓從P1.7P1.0對應(yīng)的燈為滅亮滅滅亮亮滅亮,則端口的電位應(yīng)為低高低低高高低高,寫成二進(jìn)制八位數(shù),就是01001101。

要實現(xiàn)這個,在單片機(jī)的設(shè)計上,就只需要把01001101送到P1端口就完成任務(wù)了。

這里就有一個問題,這個01001101在送到P1端口之前它在哪兒呢?在不同的位置,送法也肯定是不同的。

我們先說一種情況,就是我們的程序不做其它任何事,就只是實現(xiàn)這個功能,那么,最簡單的做法,就是這個01001101已存在程序存儲器中某個單元中,我們把程序存儲器中的這個數(shù),直接抓出來送到P1端口就行了,用語言描述其過程,就是:將程序存儲器中的某一單元中的數(shù)據(jù),當(dāng)作數(shù)值,送入P1

按這個思路,在單片機(jī)設(shè)計中,要考慮幾個問題,首先要考慮的是,讓其如何區(qū)分命令與數(shù)值,因為,在計算機(jī)中,命令與數(shù)值,都是以二進(jìn)制數(shù)來表示的,而51單片機(jī)采用哈佛結(jié)構(gòu),存在程序存儲器中的同一個區(qū)域,且并未做命令與數(shù)值的區(qū)別性標(biāo)記,也就是說,單片機(jī)控制器即不可能根據(jù)數(shù)據(jù)的特征來區(qū)分,也不可能根據(jù)其存在的物理區(qū)域來區(qū)分是命令還是數(shù)值,所以必然另想辦法。

在這個問題上,單片機(jī)是這樣設(shè)計的:程序的執(zhí)行過程,是隨時鐘一步一步地按程序存儲器單元順序從低到高地從程序存儲中取出數(shù)據(jù)并送入控制器中(遇跳轉(zhuǎn)指令則在跳轉(zhuǎn)后,從跳轉(zhuǎn)指令指定的地址開始,依然按這個規(guī)則進(jìn)行),程序存儲器中的第一個單元中的數(shù)據(jù)是必然的命令,每一命令緊隨其后的單元中的數(shù)據(jù)是否是數(shù)值、如果是,有多少個單元是數(shù)值,均由這條命令來指定,取完這一個或幾個單元的數(shù)據(jù)后,再下一個單元中的數(shù)據(jù),規(guī)定為命令。

我們可以認(rèn)為單片機(jī)可以采用這樣一種方式進(jìn)行處理(當(dāng)然還有其它方式):從程序存儲器中取出的數(shù)據(jù),進(jìn)入控制通道,通道最前面有兩道并聯(lián)且不會同時開同時關(guān)的門,命令進(jìn)甲道門,數(shù)值進(jìn)乙道門。對于將數(shù)值送入P1這個操作,其流程是:控制系統(tǒng)先收到將緊隨其后第二個單元中的數(shù)據(jù)送入P1的命令后,關(guān)閉甲門并打開乙門,之后再根據(jù)緊隨其后第一個單元中的數(shù)值所指向的P1的地址,將通向P1的門(而不是別的單元的門)全部打開,然后下一步,從程序存儲器中收到的數(shù)據(jù)就直接送到P1口了。如果僅有一個單元的數(shù)據(jù)被當(dāng)作數(shù)值傳到端口,則這三步操作完成后,乙門關(guān)而甲門開,接收下一個數(shù)據(jù)并被當(dāng)作命令送入控制器中。

再一個要解決的問題是:這個要被送入的數(shù)值存在哪個單元中?

單片機(jī)數(shù)值存放地的設(shè)計是這樣的:前面說過,它們與命令一同都存在程序存儲器中,那么存放的方式就有兩種,一種是可以由程序員任意存放于任一單元中,也可以就近存放于操作這個數(shù)值的命令之后。程序員在編程中可以任選取這兩者中的任何一種進(jìn)行數(shù)值存放,對了,后一種,就是匯編語言中說的立即數(shù),也就是上面所說到的那種處理方式。

對于前一種存放方式,我們在操作時,就必須在編程中確定并輸入其地址。至于立即數(shù)方式,則直接在立即數(shù)的操作命令中指明:這個數(shù)你們別再找了,就在我身后,也就是說,前一種方式,需要向控制系統(tǒng)專門提交(源數(shù)值)地址值,而立即數(shù)方式,不再需要提交地址值。為什么有這兩種設(shè)計?立即數(shù)方式具有一定的專用性,命令少速度快,前一種方式具有通用性但命令長而執(zhí)行時間相對較長。

下面,我們就來說具體編程,流程是找到那個將立即數(shù)送入P1的命令,然后寫出這個命令,再后面跟一個立即數(shù),這個就可以運(yùn)行了。但這里還有一個問題:51機(jī)是8位機(jī),其命令最多只能做到256條,所以,理論上,在單片機(jī)設(shè)計時,可以設(shè)計這么一條直接將立即數(shù)送入P1的命令,但是,因為256條的限制,綜合考慮,設(shè)計人員不一定會給這條命令讓路也就是說,這個單片機(jī)中不一定有這條命令。

下面,我們就來在51單片機(jī)的機(jī)器指令中找一下,看有沒有這么一條指令:我們知道,單片機(jī)中,P1屬于片內(nèi)存儲單元,其地址是90H,而在其指令系統(tǒng)表中,我們找到了一條MOV direct,#data,這條匯編指令的意思是將立即數(shù)傳遞到片內(nèi)存儲器中指定的一個單元,這個命令的機(jī)器碼就是75H,這個機(jī)器碼本身已經(jīng)指明緊隨之后的程序存儲器單元中的兩個數(shù)據(jù)為數(shù)值而不是命令,其中第一個數(shù)值direct是接收數(shù)值的單元地址,第二個數(shù)值就是要被傳送的數(shù)值010011014DH),三字節(jié)指令。這個指令比” MOV A, #data”要多一個字節(jié),它的機(jī)器命令是74H,這個命令中,已經(jīng)指明了接收數(shù)據(jù)的地址為RAM中的E0H單元,也就是累加器A,所以,不用你再寫一個接收地址了,二字節(jié)指令,專用性很強(qiáng),就是針對累加器A,當(dāng)然,你也可以寫成那個三字節(jié)指令,也當(dāng)然,這樣做真不當(dāng)然。

好了,寫匯編程序:“MOV direct,4DH”,再加一條讓其不斷重復(fù)執(zhí)行的程序,匯編編程就完成了。當(dāng)然,別忘了end,至于前面的ORG,可以不用,如果用的話,要么地址是0000H,要么前面還得加一條跳轉(zhuǎn)。

不想寫匯編,那就可以直接寫機(jī)器語言:“75H  90H 4DH”,再加一條跳轉(zhuǎn)指令,完成。

如果你用匯編,那就得用上匯編工具;如果你用機(jī)器語言,那你可以不用匯編工具,直接在燒寫工具中,在第一個單元(0000H)中寫入75H,在第二個單元中寫入90H,在第三個單元中寫入4DH,再寫入一個跳轉(zhuǎn)到第一個單元的指令,搞定,然后燒入、運(yùn)行。當(dāng)然,在這個程序中,你也可以不加跳轉(zhuǎn),但程序存儲器中后面的單元必須全部清空,否則結(jié)果不定。

說明:在以上例子中,單片機(jī)中控制器的作用,就只是開門關(guān)門。控制器接收到命令后,就是根據(jù)這個命令開相應(yīng)的門關(guān)相應(yīng)的門。

PS:精神不太好,發(fā)一下神經(jīng),如果有錯,千萬要指出,免得害人啊。

分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏9 分享淘帖 頂 踩
回復(fù)

使用道具 舉報

沙發(fā)
ID:253767 發(fā)表于 2019-10-25 07:16 | 只看該作者
謝謝分享。。『觅Y料,51黑有你更精彩!!!
回復(fù)

使用道具 舉報

板凳
ID:266429 發(fā)表于 2019-10-25 08:56 | 只看該作者
     這里介紹了MOV direct,#data  和  MOV A, #data這兩條指令,其實,在單片機(jī)設(shè)計上,前一條指令完全覆蓋了后一條指令,也就是說,即便機(jī)器并沒有設(shè)計后一條指令,也能用前一條指令來實現(xiàn)這個功能。但設(shè)計者為什么又要設(shè)計這樣一條指令呢?一個目的,就是為了讓機(jī)器能以較短的時間實現(xiàn)這個把數(shù)值送到累加器A中的功能。
     那能不能在設(shè)計中也加上一條這樣直接把數(shù)值送入P1中的二字節(jié)指令呢?當(dāng)然可以,問題是,目前256個機(jī)器指令已經(jīng)滿額了,如果要加上這么一條指令,那就得有一個現(xiàn)有的指令退出。也不是不能這樣做,如果你這樣做了,基本就是一個半新的指令集,與現(xiàn)有51機(jī)指令集就會出現(xiàn)兼容問題,除非你以后的軟硬件全部重新另起爐灶。
回復(fù)

使用道具 舉報

地板
ID:266429 發(fā)表于 2019-10-25 15:42 | 只看該作者
"至于前面的ORG,可以不用,如果用的話,要么地址是0000H,要么前面還得加一條跳轉(zhuǎn)",這個的確錯了,應(yīng)該刪除。
回復(fù)

使用道具 舉報

5#
ID:266429 發(fā)表于 2019-10-28 21:01 | 只看該作者
     所謂“立即數(shù)”,是指機(jī)器指令(機(jī)器碼)中已指定了所需傳輸?shù)臄?shù)值型數(shù)據(jù)在程序存儲器中所在單元地址的一類情況,換一種說法,就是源數(shù)據(jù)所在程序存儲器地址在機(jī)器碼中已指定。
     同樣的,我們可以思考,對于目標(biāo)地址,應(yīng)該同樣可以在機(jī)器碼中指定,“ MOV A, #data”就是一例。
     光看匯編指令,其實會讓人產(chǎn)生混亂,你無法直觀地明白“MOV A, #data” 和 “MOV direct,#data  ”的區(qū)別在哪,所以,學(xué)習(xí)匯編語言,最好也要同時學(xué)習(xí)機(jī)器碼的來由,理解之后,匯編真的是很簡單。(在這里,我想說的是,這兩條匯編指令,都采用MOV來標(biāo)記,是不太合理的)
    再說了,機(jī)器碼,其實道理很單調(diào),很好理解。
回復(fù)

使用道具 舉報

6#
ID:299519 發(fā)表于 2019-10-29 15:59 | 只看該作者
匯編太殘忍了。。。。。。
回復(fù)

使用道具 舉報

7#
ID:266429 發(fā)表于 2019-10-29 17:05 | 只看該作者
      51機(jī)的數(shù)據(jù)傳輸指令,在其學(xué)習(xí)中是一個難點。為了便于理解,我們重新分個類:
      存儲數(shù)據(jù)的地方,我們先來理解兩大類,一類就是程序存儲器,一類就是單片機(jī)內(nèi)的256字節(jié)的RAM,先不談片外RAM,也不談間接尋址的那128字節(jié)的RAM。數(shù)據(jù)的傳輸,無非是程序存儲器到RAM一類、RAM內(nèi)部之間相互傳輸一類,也就這兩類。
      程序存儲器到RAM類,前面已經(jīng)說過了,程序存儲器中的源數(shù)據(jù)有兩種存法,其中的“立即數(shù)”法已經(jīng)講解過了。“立即數(shù)”這里面也分為兩類,就是通用傳輸指令和專用傳輸指令,你如果不計較運(yùn)行效率又想偷懶,只要記住通用傳輸機(jī)器指令就行了,它能完成立即數(shù)到任何一個RAM單元的傳輸;如果你想規(guī)矩學(xué),那你無非是去找相對于目標(biāo)地址,有沒有專用傳輸指令,比如說送到累加器A,那個是有專用指令的,而如果是傳到B寄存器,查遍其指令執(zhí)行代碼表,它沒有,你只能老老實實地輸入其地址F0H。
      256字節(jié)RAM之間的數(shù)據(jù)傳輸類,首先是設(shè)計有有通用類指令,即這類指令機(jī)器碼,可以完成任何兩個RAM單元之間的數(shù)據(jù)傳輸,只要在后面寫上源地址和目的地址就可以了,這個就是完全直接尋址,即“MOV direct1,direct2”;第二種是源地址或目的地址之一,已在機(jī)器碼中表明,算是半直接尋址;第三種是源地址和目的地址,均在機(jī)器碼中指定,這個是所謂的寄存器尋址,單字節(jié)指令,速最快。這第二種和第三種是否設(shè)計有相應(yīng)的專用指令,自己可以查,如Rn與累加器之間的相互數(shù)據(jù)傳輸就設(shè)計了第三種,累加器與任一RAM之間相互傳輸就設(shè)計了第二種。
      這些東西看懂后,其它的傳輸指令,很容易自己去理解。
      PS1:我這里歸類尋址的方式,與教材上的有些不同,我不知它們把“MOV direct1,direct2”給歸到哪類去了。不過沒關(guān)系,你們覺得哪種好理解就學(xué)哪種就行。
      PS2:51機(jī)現(xiàn)有指令集未必設(shè)計得就合理,但沒法,它已通用了。如果你想設(shè)計專用芯片,你完全可以把這個指令集丟到太平洋,然后自己設(shè)計一套高效的專用指令集,設(shè)計完成后,你想不想申請專利,那是你自己的事。但是作為8位機(jī),最多也只能設(shè)計256條指令,如果是16位機(jī)及以上,那可以設(shè)計的指令,就多太多了。
      PS3:有沒有錯啊,請版主、大俠們千萬指出啊,我真的很怕害人。

回復(fù)

使用道具 舉報

8#
ID:266429 發(fā)表于 2019-10-29 17:27 | 只看該作者
      所謂的“寄存器尋址”,因為在指令中直接指定了源地址和目標(biāo)地址,所以,稱其為“完全指令尋址”,似乎更合適。
回復(fù)

使用道具 舉報

9#
ID:282850 發(fā)表于 2019-10-30 16:09 | 只看該作者
寫的很好,思路清晰,一定是一個匯編高手。我不懂匯編,知道 MOV ADD JN幾個字,三行匯編都讀不了。文章收藏了。
回復(fù)

使用道具 舉報

10#
ID:266429 發(fā)表于 2019-11-4 11:43 | 只看該作者
myemcu 發(fā)表于 2019-10-29 15:59
匯編太殘忍了。。。。。。

      我覺得匯編本身并不怎么殘忍,而是在于匯編教材,沒一本合適的,所有教材千篇一律,沒一本是象其它語言教材循序漸進(jìn)的,而是一下子把所有概念、功能和指令全拋給你,讓你不知從哪里下手。
      單片機(jī)的設(shè)計,是根據(jù)需要一個功能一個功能地弄出來的,所謂的指令,也是這樣一條一條根據(jù)需要的設(shè)計出來的,如果我們跟隨單片機(jī)設(shè)計者在當(dāng)初做設(shè)計時的思路來學(xué)習(xí),則無論是單片機(jī)的硬件方面的設(shè)計原理,還是指令的功能設(shè)計原理,都可以弄得很清楚,這樣學(xué)起來,不一定比C難。
      不懂匯編,在單片機(jī)編程方面,始終是個缺憾。我學(xué)匯編,是因為C總是讓人有霧里看花的感覺,很不舒服。
回復(fù)

使用道具 舉報

11#
ID:612635 發(fā)表于 2019-11-4 12:30 | 只看該作者
我是先會匯編,再學(xué)C語言。匯編的效率高,但不好移植。
回復(fù)

使用道具 舉報

12#
ID:266429 發(fā)表于 2019-11-4 20:16 | 只看該作者
huangxiangzhong 發(fā)表于 2019-11-4 12:30
我是先會匯編,再學(xué)C語言。匯編的效率高,但不好移植。

的確如此,但學(xué)了它,就能基本理解單片機(jī)的工作原理,對打通C、應(yīng)用C幫助很大。而且,有些底層的東西,用C比較麻煩,匯編就簡單多了。
回復(fù)

使用道具 舉報

13#
ID:514974 發(fā)表于 2019-11-5 08:22 | 只看該作者
很好,思路清晰,文章收藏了!
謝謝分享!好資料!
回復(fù)

使用道具 舉報

14#
ID:266429 發(fā)表于 2019-11-5 11:32 | 只看該作者
我們把前面說的數(shù)據(jù)傳輸,從單片機(jī)設(shè)計者的角度疏理一下(以下僅以8位數(shù)據(jù)即一字節(jié)數(shù)為例):
首先說程序程序器到RAM的數(shù)據(jù)傳輸。
單片機(jī)在芯片功能設(shè)計中,很重要的也是最基本的一個功能項目,就是將程序存儲器中保存的數(shù)值型數(shù)據(jù),送入單片機(jī)內(nèi)的RAM中。設(shè)計者首先想到的,是設(shè)計這樣一條指令:這條指令指出要從程序存儲器中將某一地址中的數(shù)據(jù)送入RAM,而源地址和目標(biāo)地址均在這條指令后明確給出,這樣就成為“指令+目標(biāo)地址+源地址”式指令。然后,設(shè)計想到為了縮短指令執(zhí)行時長,就想到設(shè)計另一種指令:將源地址包含在指令中,目標(biāo)地址仍然在指令后給出,這就是“指令(含源地址)+目標(biāo)地址”式指令,也就是所謂的立即尋址方式。根據(jù)這個思路,再設(shè)計一種指令以繼續(xù)縮短運(yùn)行時長,將源地址和目標(biāo)地址均包含在指令中,成為“指令(含源地址+目標(biāo)地址)”,這個算是立即尋址方式中的一個子集。還有很重要的一種,也是我們自然會想到的,就是將目標(biāo)地址包含在指令中,而源地址則仍在指令后明確給出。這樣,我們就有了實現(xiàn)程序存儲器到RAM的四種設(shè)計傳輸指令的思路。
設(shè)計思路歸設(shè)計思路,在實際設(shè)計中,因為要綜合考慮很多因素,所以,我們所用的單片機(jī)中,這四類指令不一定都有,實際上,第一種方式并沒有設(shè)計相應(yīng)的指令。第二種方式有,就是“MOV direct,#data”,時鐘3,對應(yīng)一個機(jī)器碼,可以傳輸?shù)饺我釸AM單元;第四種方式也有,但僅設(shè)計了對累加器A,也就是說,如果指定了源地址,那這個數(shù)據(jù)只能傳輸給累加器A,也就是說,這個數(shù)據(jù)如果想傳輸?shù)狡渌胤,只能先通過A中轉(zhuǎn),這個就是兩條MOVX指令,時鐘4或5,對應(yīng)2個機(jī)器碼,所謂的變址尋址方式;第三種方式也有,僅設(shè)計了對累加器A及工作寄存器Rn(這里暫不談間接RAM,這個間接RAM是后面的設(shè)計才考慮進(jìn)去的),就是“MOV A,#data”和“MOV Rn,#data”,時鐘2,對應(yīng)1+8個機(jī)器碼(n從0到7,每個R對應(yīng)一個機(jī)器碼)。
PS1:如果你覺得上面的設(shè)計不合理,你完全可以自己設(shè)計芯片,當(dāng)然,想推廣出去比較難,估計也只能你自己用了。
PS2:以前說過,每一條機(jī)器碼,在芯片中都對應(yīng)有一套硬件電路,所以,指令越多,則芯片的晶體管數(shù)越多。
回復(fù)

使用道具 舉報

15#
ID:266429 發(fā)表于 2019-11-6 09:42 | 只看該作者
      補(bǔ)充一點:程序存儲器到RAM的數(shù)據(jù)傳輸指令的設(shè)計,很重要的一點是要考慮到51機(jī)的程序存儲器是十六位地址,片內(nèi)RAM是八位地址。

      下面我們疏理一下單元地址(包括源和目標(biāo))的給出方式。
      其實可以分為兩大類,第一類是在機(jī)器指令碼中包含,第二類是在機(jī)器指令碼后面給出地址值。
第一類往下可以這樣細(xì)分類:機(jī)器碼中包含源與目標(biāo)地址、機(jī)器碼中只包含源地址、機(jī)器碼中只包含目標(biāo)地址,三種。
      第二類往下可以有兩種細(xì)分類方法:一種就是按上面的分法,另一種分類法是重點,分為以下三種:
      1.        直接給出地址值。匯編中的“direct”就是地址值;
      2.        將地址值放在某一RAM單元中。51機(jī)中的“某一RAM”其實只有2X4個,就是Ri,再加一個十六位的DPTR;
      3.        該地址值需經(jīng)計算得出,得出的結(jié)果放在某一RAM單元中,然后再用第2種指令來尋址傳輸,但這樣做就用到了多個指令了,不能算作一條機(jī)器指令,所以,就設(shè)計這樣一類指令:將計算命令包含在這條指令中,即這條指令明確指明要進(jìn)行計算的原始數(shù)據(jù)在哪些單元中、要進(jìn)行什么樣的計算、計算完成后的結(jié)果直接作為地址值(包含指明物理存儲器的種類)去尋址并進(jìn)行傳輸,一個字節(jié)就全部搞定,即為一字節(jié)指令。這個其實就是51機(jī)指令中的所謂的變址尋址,兩條機(jī)器指令,對應(yīng)兩條匯編指令,指明物理存儲器為片內(nèi)程序存儲器,也就是說僅針對片內(nèi)程序存儲器的尋址,至于對RAM的,對不起,沒設(shè)計這樣的指令,只能自己去編程計算地址值,然后采用第2種來尋址并傳輸。
回復(fù)

使用道具 舉報

16#
ID:638805 發(fā)表于 2019-11-9 19:37 | 只看該作者
支持分享
回復(fù)

使用道具 舉報

17#
ID:477152 發(fā)表于 2019-11-30 19:50 | 只看該作者
思路清晰,文章收藏了!
回復(fù)

使用道具 舉報

18#
ID:266429 發(fā)表于 2020-1-6 08:47 | 只看該作者
匯編指令中的地址,包括源地址和目標(biāo)地址,還有一個很重要的分類方法,那就是地址值的可變性和不可變性,可變地址類,其地址值在程序運(yùn)行過程中是可以通過程序運(yùn)行計算得出的,而不可變地址類,則只能在編程時由程序員給出唯一值。如MOV A,direct中,A是不可變地址,direct則是可變地址;JB bit,rel中,bit和rel都是不可變地址。
可變地址類,在編程中具有靈活性;不可變地址,則執(zhí)行周期短,但編程中實在是不靈活。
回復(fù)

使用道具 舉報

19#
ID:681890 發(fā)表于 2020-1-6 09:01 | 只看該作者
真是個好平臺
回復(fù)

使用道具 舉報

20#
ID:681905 發(fā)表于 2020-1-6 09:18 | 只看該作者
謝謝大佬
回復(fù)

使用道具 舉報

21#
ID:1110944 發(fā)表于 2025-4-6 22:31 | 只看該作者
思路清晰,文章收藏了!
回復(fù)

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規(guī)則

手機(jī)版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機(jī)教程網(wǎng)

快速回復(fù) 返回頂部 返回列表