久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 4351|回復: 20
收起左側

匯編之從單片機設計者的角度來學習單片機

  [復制鏈接]
ID:266429 發表于 2019-10-24 21:34 | 顯示全部樓層 |閱讀模式

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

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

要實現這個,在單片機的設計上,就只需要把01001101送到P1端口就完成任務了。

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

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

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

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

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

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

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

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

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

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

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

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

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

說明:在以上例子中,單片機中控制器的作用,就只是開門關門。控制器接收到命令后,就是根據這個命令開相應的門關相應的門。

PS:精神不太好,發一下神經,如果有錯,千萬要指出,免得害人啊。

回復

使用道具 舉報

ID:253767 發表于 2019-10-25 07:16 | 顯示全部樓層
謝謝分享!!!好資料,51黑有你更精彩!!!
回復

使用道具 舉報

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

使用道具 舉報

ID:266429 發表于 2019-10-25 15:42 | 顯示全部樓層
"至于前面的ORG,可以不用,如果用的話,要么地址是0000H,要么前面還得加一條跳轉",這個的確錯了,應該刪除。
回復

使用道具 舉報

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

使用道具 舉報

ID:299519 發表于 2019-10-29 15:59 | 顯示全部樓層
匯編太殘忍了。。。。。。
回復

使用道具 舉報

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

回復

使用道具 舉報

ID:266429 發表于 2019-10-29 17:27 | 顯示全部樓層
      所謂的“寄存器尋址”,因為在指令中直接指定了源地址和目標地址,所以,稱其為“完全指令尋址”,似乎更合適。
回復

使用道具 舉報

ID:282850 發表于 2019-10-30 16:09 | 顯示全部樓層
寫的很好,思路清晰,一定是一個匯編高手。我不懂匯編,知道 MOV ADD JN幾個字,三行匯編都讀不了。文章收藏了。
回復

使用道具 舉報

ID:266429 發表于 2019-11-4 11:43 | 顯示全部樓層
myemcu 發表于 2019-10-29 15:59
匯編太殘忍了。。。。。。

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

使用道具 舉報

ID:612635 發表于 2019-11-4 12:30 | 顯示全部樓層
我是先會匯編,再學C語言。匯編的效率高,但不好移植。
回復

使用道具 舉報

ID:266429 發表于 2019-11-4 20:16 | 顯示全部樓層
huangxiangzhong 發表于 2019-11-4 12:30
我是先會匯編,再學C語言。匯編的效率高,但不好移植。

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

使用道具 舉報

ID:514974 發表于 2019-11-5 08:22 | 顯示全部樓層
很好,思路清晰,文章收藏了!
謝謝分享!好資料!!
回復

使用道具 舉報

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

使用道具 舉報

ID:266429 發表于 2019-11-6 09:42 | 顯示全部樓層
      補充一點:程序存儲器到RAM的數據傳輸指令的設計,很重要的一點是要考慮到51機的程序存儲器是十六位地址,片內RAM是八位地址。

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

使用道具 舉報

ID:638805 發表于 2019-11-9 19:37 | 顯示全部樓層
支持分享
回復

使用道具 舉報

ID:477152 發表于 2019-11-30 19:50 | 顯示全部樓層
思路清晰,文章收藏了!
回復

使用道具 舉報

ID:266429 發表于 2020-1-6 08:47 | 顯示全部樓層
匯編指令中的地址,包括源地址和目標地址,還有一個很重要的分類方法,那就是地址值的可變性和不可變性,可變地址類,其地址值在程序運行過程中是可以通過程序運行計算得出的,而不可變地址類,則只能在編程時由程序員給出唯一值。如MOV A,direct中,A是不可變地址,direct則是可變地址;JB bit,rel中,bit和rel都是不可變地址。
可變地址類,在編程中具有靈活性;不可變地址,則執行周期短,但編程中實在是不靈活。
回復

使用道具 舉報

ID:681890 發表于 2020-1-6 09:01 | 顯示全部樓層
真是個好平臺
回復

使用道具 舉報

ID:681905 發表于 2020-1-6 09:18 | 顯示全部樓層
謝謝大佬
回復

使用道具 舉報

ID:1110944 發表于 2025-4-6 22:31 | 顯示全部樓層
思路清晰,文章收藏了!
回復

使用道具 舉報

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

本版積分規則

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

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 天天干天天插 | 亚洲精品一区二区三区 | 国产无人区一区二区三区 | 亚洲一区二区三区在线播放 | 国产日韩一区二区 | 国产精品精品久久久 | 久久小视频| 中文字幕精品一区二区三区精品 | 国产亚洲一区二区三区 | 国产黄色在线观看 | 国产高清免费视频 | 亚洲欧美在线观看 | 欧美视频在线免费 | 草草视频在线免费观看 | 精品国产乱码久久久久久久久 | 亚洲精品免费在线 | 一区二区三区四区在线视频 | 亚洲精品一区二区 | 久久9久 | 中文字幕一区二区三区在线观看 | 欧美日韩电影免费观看 | 黄色一级电影免费观看 | 日韩福利在线观看 | 成人午夜免费视频 | 亚洲精品九九 | 欧美激情综合五月色丁香小说 | 一级做a爰片性色毛片 | 日韩网站免费观看 | 欧美1区2区 | 范冰冰一级做a爰片久久毛片 | 超碰在线影院 | 在线免费观看欧美 | 国产日韩欧美一区二区 | 亚州成人| 精品一区二区三区在线观看国产 | 精品亚洲一区二区 | 免费看国产一级特黄aaaa大片 | 日韩高清国产一区在线 | 国产真实精品久久二三区 | 日韩亚洲欧美综合 | 欧美日韩视频一区二区 |