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

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
樓主: newlined
打印 上一主題 下一主題
收起左側

請教各位大神一個匯編語言堆棧大小計算的問題

[復制鏈接]
41#
ID:227818 發表于 2022-7-15 11:15 | 只看該作者
188610329 發表于 2022-7-14 21:07
R0~R7 屬于 通用寄存器, 是不能PUSH的。
如果是完全自己寫的代碼,配合USING 可以用 PUSH AR0~AR7 方式 ...

您好,四組寄存器都已經用到了,其中有1組還是有2個同級別的低級中斷共用的.考慮到這2個低級別中斷不會同時被單片機響應,也沒有用它們傳遞參數,只是用R0和R1訪問間接地址,應該是不會沖突吧。
回復

使用道具 舉報

42#
ID:401564 發表于 2022-7-15 14:06 | 只看該作者
我感覺你還是把代碼上傳上來吧
既然你說是多年前的程序,那就說明以前的代碼是對的,問題估計就是出現你自己的代碼上
把你自己的代碼上傳就行,不用把整個程序都上傳的
你的代碼在程序中是哪里調用的,如果是中斷,就把中斷中調用的位置和代碼上傳就行
MOV R0,#20H  之類的,它總不會連這也算商業機密吧
現在都是一群人在亂猜,壓根就不知道你程序一個大概的流程
很有可能這只是一個簡單的問題而已,卻搞得那么復雜
回復

使用道具 舉報

43#
ID:624769 發表于 2022-7-15 15:34 | 只看該作者
newlined 發表于 2022-7-15 11:15
您好,四組寄存器都已經用到了,其中有1組還是有2個同級別的低級中斷共用的.考慮到這2個低級別中斷不會同 ...

看你另外一個帖子, 你再找單片機原理的書? 所以,問題出在,你并不理解你的單片機?
我之前34樓的問題,你也沒有回復,所以,我也不知道該從哪里可以幫到你,但是,個人覺得堆棧的問題,概率不大。考慮到你可能存在的“重入”問題,簡單跟你說幾個關鍵原理。
CSEG AT 0000H
LJMP  MAIN
CSEG AT 0003H
LJMP  EX0_INT

MAIN:
; 此處省略外部中斷初始化程序
MAIN_Loop:
LCALL   Delay
SJMP   MAIN_Loop

EX0_INT:
PUSH   PSW
MOV    PSW,#08H
USING   1
LCALL  Delay
POP    PSW
RETI

Delay:
MOV   R7,#100H
DJNZ  R7,$
RET

這個例子,完全是為了 舉例子而舉例子。

我們可以看到  Delay 這個函數, 重入了, 但是,有影響么? 沒有!!!, 只要確保  主程序所在 寄存器組, 不等于 中斷使用的寄存器組, R0~R7, 是不會受 重入影響的。

我們再看這個例子:
CSEG AT 0000H
LJMP  MAIN
CSEG AT 0003H
LJMP  EX0_INT

MAIN:
; 此處省略外部中斷初始化程序
MAIN_Loop:
LCALL   Delay
SJMP   MAIN_Loop

EX0_INT:           ;這次,中斷里我們不切換寄存器
;PUSH   PSW
;MOV    PSW,#08H
;USING   1
LCALL  Delay
;POP    PSW
RETI

Delay:
USING    0            
PUSH   AR7             ; 函數內部,保護現場, 這也是常規意義的, “可重入函數”
MOV   R7,#100H
DJNZ  R7,$
POP    AR7
RET


這個例子,我們依然 重入了,   但是,有影響么??, 沒有!!!!
所以,重入問題,是完全可以  靠人解決的, 編譯器,絕對不會比人“更高級”,你既然現在在折騰匯編代碼,就不要考慮 C 可能的問題,畢竟C 你是依賴編譯器的,而,匯編,你只能依靠你自己(因為你的代碼要“保密”,所以你也靠不到我們)。


基本上,目前從你這里得到的信息,只能幫到你這里了, 當然,如果你回復了 我在34樓的問題,也許可以給多你一點支持。

回復

使用道具 舉報

44#
ID:883242 發表于 2022-7-15 20:13 | 只看該作者
現在越來越混亂了。樓主在20樓說重入警告,這是c51獨有的,匯編的重入問題完全由用戶控制,根本不可能出現警告,然后樓主又說用匯編。樓主連自己用的是個啥都不知道,大家還是散了吧。
回復

使用道具 舉報

45#
ID:227818 發表于 2022-7-16 08:06 | 只看該作者
Y_G_G 發表于 2022-7-15 14:06
我感覺你還是把代碼上傳上來吧
既然你說是多年前的程序,那就說明以前的代碼是對的,問題估計就是出現你自己 ...

是這樣,是一家小公司,硬件都在那里,大家都可以看到,軟件是這家公司的支柱,老板有交代,不好貼,請大家原諒。在在大家的指導下,把DPTR保護后,跑了1天多,軟件不死機了,謝謝大家。
回復

使用道具 舉報

46#
ID:227818 發表于 2022-7-16 08:12 | 只看該作者
本帖最后由 newlined 于 2022-7-16 08:42 編輯
188610329 發表于 2022-7-15 15:34
看你另外一個帖子, 你再找單片機原理的書? 所以,問題出在,你并不理解你的單片機?
我之前34樓的問題,你也 ...

這一段程序我看懂了,函數重入后,對這個函數用到的寄存器,函數被調用之前用到,函數調用完成后,還要用到的要保護后,就不會出問題。有了問題后,總是漫天找問題。
回復

使用道具 舉報

47#
ID:227818 發表于 2022-7-16 08:24 | 只看該作者
Hephaestus 發表于 2022-7-15 20:13
現在越來越混亂了。樓主在20樓說重入警告,這是c51獨有的,匯編的重入問題完全由用戶控制,根本不可能出現 ...

不好意思,最近記憶力嚴重衰退,連老板都笑話我,也許我記串了。有一次,一個問題我們兩個人,商討后解決了,過了幾天,我說那個問題怎么辦,老板說我們兩個商量后不是已經解決了嗎,如何如何解決的,我聽后好久才回憶起來。
對51的匯編,我是邊學邊用,實際上,我一般是先用KEIL C寫出來,運行通過后再按照這個思路,改成匯編。這個匯編程序中,有一個函數,主程序和中斷都調用,也許是出問題,我就復制了一份,另起一個名字,函數內部用到的直接尋址的地址,用另外的地址,運行通過了。
回復

使用道具 舉報

48#
ID:149642 發表于 2022-7-16 08:38 | 只看該作者
這么復雜的程序,空間夠用的情況下直接使用全局變量不好么,隨便你咋中斷,隨便你咋調用,我都不用壓堆的.
回復

使用道具 舉報

49#
ID:227818 發表于 2022-7-16 08:42 | 只看該作者
188610329 發表于 2022-7-14 20:06
如果,你進入中斷,用的是不同的寄存器組, 那么,你對 R0 的操作,是不會影響 主程序的 R0的,因為,此  ...

程序中,四個工作區都用到了,其中兩個低級中斷共用一個區,因為不會同時被單片機響應,不會出問題。以前的堆棧,設在50H到64H之間,64H到80H有的地址用了,有的還空著,我就把用的改在一起,空出來的跟64H連在一起做堆棧.
回復

使用道具 舉報

50#
ID:883242 發表于 2022-7-16 08:51 | 只看該作者
newlined 發表于 2022-7-16 08:42
程序中,四個工作區都用到了,其中兩個低級中斷共用一個區,因為不會同時被單片機響應,不會出問題。以前的堆 ...

越來越混亂了,我在32樓問你用到idata了嗎?你在39樓回答用到了。只有用到了80h以上空間才會用到idata,而C51編譯器會自動把堆棧分配到idata上面。如果你用匯編的話,也應該利用高128字節來做堆棧,然而你又說堆棧在50h和64h之間???到底是怎么寫的?這種空對空的說根本解決任何問題,按42樓建議,如果原程序是商業機密你不可以貼,但是你自己寫的那部分,你拿捏不準的地方不貼出來,沒有討論的價值,也不太可能有人能提出關鍵性建議。
回復

使用道具 舉報

51#
ID:887371 發表于 2022-7-16 10:13 | 只看該作者
本帖最后由 datouyuan 于 2022-7-16 10:22 編輯
newlined 發表于 2022-7-16 08:42
程序中,四個工作區都用到了,其中兩個低級中斷共用一個區,因為不會同時被單片機響應,不會出問題。以前的堆 ...

看來你這代碼問題很大。
51的堆棧要安排在ram的最后。
例如你需要32字節堆棧,那么堆棧空間為0xe0~0xff。初始化SP要小于等于0xe0。
例如你需要48字節堆棧,那么堆棧空間為0xd0~0xff。初始化SP要小于等于0xd0。
小于0x80區域(data區),可以直接尋址,變量盡量安排在此區域。
>=0x80區域(idata區),只能間接尋址,變量在data區安排不下時(重要!!!),將數組變量、使用不頻繁的變量安排在此區域。

編寫匯編代碼時,要確定所有變量使用了多少字節,例如使用了150個字節,那么SP應等于150,那么堆棧空間為150~0xff(共106字節)。
這帖子中,我提到的僅僅是些基本原則,估計樓主獨立解決應該比較困難,建議樓主將代碼交給有經驗的幫忙。
回復

使用道具 舉報

52#
ID:887371 發表于 2022-7-16 11:58 | 只看該作者
newlined 發表于 2022-7-16 08:24
不好意思,最近記憶力嚴重衰退,連老板都笑話我,也許我記串了。有一次,一個問題我們兩個人,商討后解決 ...

這樣只是解決了編譯器報警問題。
前提你要保證你的業務邏輯是正確的,假如業務邏輯有bug,即使你添加了再入屬性,或者復制一份,都不能解決問題。
回復

使用道具 舉報

53#
ID:624769 發表于 2022-7-16 18:00 | 只看該作者
newlined 發表于 2022-7-16 08:42
程序中,四個工作區都用到了,其中兩個低級中斷共用一個區,因為不會同時被單片機響應,不會出問題。以前的堆 ...

堆棧不能這么搞, 堆棧是向上增長的,所以應該分配在內存的最末尾,而且,我不知道你用的什么單片機,最初的編寫環境是怎么樣的,照理你這代碼 如果用的標準 A51 規范來寫,你所有的變量聲明不用  SEGMENT 來定的么? 不然,維護起來有多復雜?正常不應該是這么一個套路么?My_DATA SEGMENT DATA        ;預約DATA 內存
RSEG My_DATA
   ABC:           DS     1
   EFG:           DS     1
   TEMP1:       DS     1
   TEMP2:       DS     1
My_IDATA SEGMNET IDATA   ;預約IDATA 內存
RSEG My_IDATA
   REV_BUF:      DS     32
   Disp_BUF:      DS     8
   ?STACK:        DS     1

CSEG   AT   0000H
LJMP      MAIN

Main_PROG  SEGMENT CODE
RSEG    Main_PROG
MAIN:
       MOV     SP,#?STACK-1                ;定位堆棧起點

       SJMP     $

END

你那個代碼,到底是怎么折騰的,能夠把 堆棧地址夾在那么奇怪的一個地方的?


評分

參與人數 1黑幣 +15 收起 理由
datouyuan + 15 很給力!

查看全部評分

回復

使用道具 舉報

54#
ID:227818 發表于 2022-7-18 16:39 | 只看該作者
datouyuan 發表于 2022-7-16 10:13
看來你這代碼問題很大。
51的堆棧要安排在ram的最后。
例如你需要32字節堆棧,那么堆棧空間為0xe0~0xff ...

堆棧以前就是那樣設定的。再就是提到堆棧可以安排在80H到FFH之間,我以前不知道,我以為這些地址只可以利用R0,R1間接尋址來訪問,使用。
回復

使用道具 舉報

55#
ID:227818 發表于 2022-7-18 16:42 | 只看該作者
datouyuan 發表于 2022-7-16 11:58
這樣只是解決了編譯器報警問題。
前提你要保證你的業務邏輯是正確的,假如業務邏輯有bug,即使你添加了 ...

業務邏輯保證是正確的,里邊用到的地址都改了,不會沖突。
回復

使用道具 舉報

56#
ID:227818 發表于 2022-7-18 16:53 | 只看該作者
188610329 發表于 2022-7-16 18:00
堆棧不能這么搞, 堆棧是向上增長的,所以應該分配在內存的最末尾,而且,我不知道你用的什么單片機,最 ...

我知道堆棧是向上生長的,程序中以前就是那樣設定的,我也不知道為什么,我設定的話起碼會設在80H之前,我原以為堆棧的最大地址是7FH,80H到FFH是間接地址,不可以做堆棧。程序對DPTR保護后,運行了2天。沒有再出以前的問題。在這里請教下,您前邊的帖子里提到的指令 PUSH AR0  ,PUSH  AR1 是在哪里能學到,一般的書里都沒有。再就是這個帖子里的偽指令,在哪里可以學到?一般的書里也沒有,謝謝。
回復

使用道具 舉報

57#
ID:227818 發表于 2022-7-18 17:01 | 只看該作者
買了這2本書,也沒有起多大作用,講到中斷,也只是說,保護現場,恢復現場,也沒有具體的說要恢復那些東西,還不如在本帖中學到的東西多

IMG_20220718_165504[1].jpg (3.82 MB, 下載次數: 717)

IMG_20220718_165504[1].jpg
回復

使用道具 舉報

58#
ID:227818 發表于 2022-7-18 17:03 | 只看該作者
還有這一本

IMG_20220718_165516[1].jpg (3.14 MB, 下載次數: 705)

IMG_20220718_165516[1].jpg
回復

使用道具 舉報

59#
ID:227818 發表于 2022-7-18 17:07 | 只看該作者
@ 188610329,單片機是STC 8H
回復

使用道具 舉報

60#
ID:227818 發表于 2022-7-18 17:08 | 只看該作者
也許看這些書需要一定的功力,我還遠遠不夠。
回復

使用道具 舉報

61#
ID:624769 發表于 2022-7-18 19:36 | 只看該作者
newlined 發表于 2022-7-18 16:53
我知道堆棧是向上生長的,程序中以前就是那樣設定的,我也不知道為什么,我設定的話起碼會設在80H之前, ...

AR0~AR7 是偽地址, 屬于KEIL A51 專用,在KEIL的幫助里面可以找到,一般講匯編的書,不會寫,要講KEIL的書才會寫, 主要是為了彌補 A51 指令的空白, 你如果已經打了一點匯編基礎,你會知道, 你如果要把R7 的東西復制給 R6, 是不能直接復制的,這個時候,就可以用到 “偽地址”: MOV  R6,AR7  來達到目的, 此時的 AR7, 其實是一個 指向 R7 所在的直接地址。相當于: MOV R6,07H  這條指令,唯一的好處是,AR7 可以指代 4組通用寄存器的 任何一個組,編譯的時候,會幫你自動 改直接地址。所以,同樣道理,PUSH 只能PUSH 直接地址,我們可以用PUSH AR7來填補無法 PUSH R7的空白。 其實主要內容就這么點。你要還有興趣 可以去KEIL的 幫助里面搜一下。

再跟你講一下SP, SP其實就是指針,你仔細看51方面的書,會提到 3個8位地址指針,2個16位指針,分別對應的就是: R0,R1,SP,DPTR,PC 這5個指針。 其中: SP是半自動,PC 是全自動, R0,R1,DPTR是全手動。所以,基于SP是8位指針的特性,他的工作原理和 R0,R1 是一樣的,就是訪問的 IDATA 間接尋址內存。而PUSH 和 POP 指令你可以理解成:PUSH ACC
PUSH PSW
........
POP  PSW
POP  ACC
RETI

//以下代碼不存在,是解釋上面代碼的動作。
MOV   @SP,ACC
INC   SP
MOV   @SP,PSW
INC   SP
..............
DEC  SP
MOV  PSW,@SP
DEC  SP
MOV  ACC,@SP
RETI

通過這個代碼,我們可以看到。其實,你用 R0,R1 完全可以 軟件模擬出 PUSH POP 指令。 反過來,指針不夠用的時候, SP也可以臨時拿來當 R0,R1 的替補用。

最后,說一下,代碼是死的,就看你怎么用。說到底,還是要去體會和理解 單片機的工作原理。



回復

使用道具 舉報

62#
ID:401564 發表于 2022-7-19 01:18 | 只看該作者

你要看的是這一本書,網上應該可以搜索到不要錢的PDF版本,也可以買二手的,馬云家30塊左右,超過這個價錢就不要買了,我買的時候才二十多塊
匯編沒有那么復雜的,不要糾結堆棧了,8051是軟件堆棧,我從來都不去管它的,等到你用到了硬件堆棧,你才會體驗到匯編的毛病而且8051是復雜指令,功能多得很,你要是用到精簡指令,你就會更加的體會到匯編的無聊
現在的編譯器效率已經非常不錯了,優先選擇C語言,實在不行了再用匯編
回復

使用道具 舉報

63#
ID:227818 發表于 2022-8-1 08:16 | 只看該作者
前一段時間,我母親生病住院,我去陪床,我母親出院那一天,我父親很高興,去做飯,又燙傷了腳,我沒有時間仔細看這個帖子,很抱歉。
回復

使用道具 舉報

64#
ID:227818 發表于 2022-8-1 08:21 | 只看該作者
188610329 發表于 2022-7-18 19:36
AR0~AR7 是偽地址, 屬于KEIL A51 專用,在KEIL的幫助里面可以找到,一般講匯編的書,不會寫,要講KEIL的 ...

看了這個帖子,我明白了,AR7是不是已經宏定義成了07H?我以前對地址了解不透徹,看來我要對這方面仔細揣摩。
回復

使用道具 舉報

65#
ID:227818 發表于 2022-8-1 08:25 | 只看該作者
Y_G_G 發表于 2022-7-19 01:18
你要看的是這一本書,網上應該可以搜索到不要錢的PDF版本,也可以買二手的,馬云家30塊左右,超過這個價錢就 ...

在網上我搜到了這本書的下載網站,但好像需要注冊,需要電話號碼什么的。在淘寶上有一家賣30幾元,但需要45天發貨,不知道怎么回事。
回復

使用道具 舉報

66#
ID:401564 發表于 2022-8-1 13:17 | 只看該作者
這么些天了,還沒有搞明白這個?
00H-1FH  這就是R0-R7的幾個工作組
20H-2FH 這是可以位尋址的,位地址是從00H開始的,字節地址也有00H,通過指令來區分是位操作還是字節操作
SETE 00H 這是位操作
MOV 00H,#255 這是字節操作

一般是編寫代碼的時候,00H-1FH留給工作組使用,20H-2FH留給位尋址用
所以,你一般看到的用到內存的,都是多30H開始的

回復

使用道具 舉報

67#
ID:624769 發表于 2022-8-1 17:21 | 只看該作者
newlined 發表于 2022-8-1 08:21
看了這個帖子,我明白了,AR7是不是已經宏定義成了07H?我以前對地址了解不透徹,看來我要對這方面仔細揣 ...

AR7  不一定是 07H,  也可能是 0FH, 17H 或者 1FH。 這牽涉到另一條 偽指令: USING  ,  當代碼向上搜索 找到USING 0 則編譯的時候會把  PUSH AR7  當作 PUSH 07H 來編譯, 如果找到 USING 1 則會在編譯的時候 把 PUSH AR7 當作 PUSH 0FH 來編譯。 所以 AR7 不是絕對的,是可變的,好處是,如果更換換寄存器組,你可以不需要一行行代碼去把 代表R7地址手動更改。缺點是,USING 必需要控制好。
回復

使用道具 舉報

68#
ID:227818 發表于 2022-8-4 09:59 | 只看該作者
188610329 發表于 2022-8-1 17:21
AR7  不一定是 07H,  也可能是 0FH, 17H 或者 1FH。 這牽涉到另一條 偽指令: USING  ,  當代碼向上搜索  ...

這一段我還不理解,但我會盡量避免出現這個問題,以后我會慢慢領會。現在我遇到一個新的問題,就是單片機是STC的8H系列,您肯定知道,它對扇區的讀寫命令是類似這樣的:

        ISP_CMD                        EQU                0C5H                        ;ISP命令寄存器
        ISP_CONTR                EQU                0C7H                        ;ISP控制寄存器
        ISP_TPS                        EQU                0F5H                        ;ISP等待時間寄存器

        MOV                          ISP_CONTR,#ENABLE_ISP
        MOV                               ISP_CMD,#01H                  ; 讀扇區
        MOV                          ISP_TPS,#0CH  ;
這一段程序在主程序中用到了,在一個中斷中也用到了,在中斷中,對 ISP_CMD,ISP_CONTR進行壓棧保護?就是 PUSH ISP_CMD,PUSH ISP_CONTR ,退出中斷時 再 POP ISP_CONTR,POP ISP_CMD,這樣保護能達到目的嗎?編譯是通過了,但我沒有把握,您看可以嗎?
回復

使用道具 舉報

69#
ID:227818 發表于 2022-8-4 11:12 | 只看該作者
Y_G_G 發表于 2022-8-1 13:17
這么些天了,還沒有搞明白這個?
00H-1FH  這就是R0-R7的幾個工作組
20H-2FH 這是可以位尋址的,位地址是從0 ...

這個地址我基本明白了,但對地址的運用上,還是不行,我可能需要一些實踐才能領會。
回復

使用道具 舉報

70#
ID:624769 發表于 2022-8-4 14:56 | 只看該作者
newlined 發表于 2022-8-4 09:59
這一段我還不理解,但我會盡量避免出現這個問題,以后我會慢慢領會。現在我遇到一個新的問題,就是單片機 ...

要說保護的話……
ISP_CMD, ISP_CONTR,之外,ISP_ADDRH, ISP_ADDRL 這些都要一起保護。
但是這些都沒用。嚴格來講,STC系列而言, ISP/IAP操作是唯一無法保護現場的操作。
因為: IAP_TRIG  這個啟動指令, 需要連續發送兩條 0x5A, 和 0xA5 的啟動指令,這個是絕對不允許被打斷的。所以,一般,會需要在程序中,先  CLR EA,禁止中斷, 等所有 IAP操作完成 后 再次 SET EA 允許中斷,這個才是關鍵。所以說,了解單片機的工作原理,還是重點中的重點。而如果在 主程序中已經禁止了中斷,那么,相關操作就不需要 被PUSH和POP來現場保護了。

最后:IAP_TPS 是STC8系列用來設置 IAP操作速度的,理論上來說,只要你單片機不要不停的改變速度, MOV IAP_TPS,#0CH 之需要執行一次,里面的值是不會,也不需要再修改的。所以,通常來說,IAP_TPS 也是沒有必要PUSH和POP的。
回復

使用道具 舉報

71#
ID:227818 發表于 2022-8-4 15:56 | 只看該作者
188610329 發表于 2022-8-4 14:56
要說保護的話……
ISP_CMD, ISP_CONTR,之外,ISP_ADDRH, ISP_ADDRL 這些都要一起保護。
但是這些都沒 ...

真是的,您提醒了我,ISP_ADDRH, ISP_ADDRL我沒有保護,程序運行主程序*ISP_ADDRH, ISP_ADDRL
回復

使用道具 舉報

72#
ID:227818 發表于 2022-8-4 16:00 | 只看該作者
筆記本的鍵盤不好用,可能是我前一段時間摔了一下.
回復

使用道具 舉報

73#
ID:227818 發表于 2022-8-4 16:11 | 只看該作者
程序運行過程中,有是會出現問題,可能是這個原因,兩條 0x5A, 和 0xA5 的啟動指令之前,中斷是關的,之后打開了,實際上這個是以前的程序,我后來補充了一些程序中,尤其是中斷中用到了操作EEPROM的語句,沒有對主程序中操作EEPROM的現場保護。我如果對DPTR,ISP_CMD, ISP_CONTR,ISP_ADDRH, ISP_ADDRL保護了,就沒有問題了吧。
回復

使用道具 舉報

74#
ID:624769 發表于 2022-8-4 18:10 來自手機 | 只看該作者
手機打字,我就長話短說了。 首先,trig指令發送前關中斷,發送后開中斷,是最低底線。 其次,我不太清楚你程序如何設計,stc8系列是支持movc讀取eeprom的,所以,我的話,所有讀指令都是movc完成的,寫指令才會用iap指令,所以基本上是不需要保護iap相關寄存器,只需要保護dptr就可以的。 最后,牽涉到架構了,如果有可能,所有的寫,擦eeprom的行為,集中在一個函數,或者一個中段中完成,對整個程序是最優的。
回復

使用道具 舉報

75#
ID:227818 發表于 2022-8-6 14:32 | 只看該作者
讀指令movc可以不需要保護iap相關寄存器嗎?我仔細揣摩下。
回復

使用道具 舉報

76#
ID:624769 發表于 2022-8-7 17:59 | 只看該作者
newlined 發表于 2022-8-6 14:32
讀指令movc可以不需要保護iap相關寄存器嗎?我仔細揣摩下。

STC的 Eeprom 是把 Flash 空間模擬成 Eeprom 來操作,尤其是STC8系列,他在物理上就是 ROM的一部分。所以,只需要把它當 ROM來讀就可以了。那么讀取ROM的方式事就是:

MOV DPTR,#16位絕對地址
CLR A
MOVC A,@A+DPTR

就能讀取了。整個過程沒有 IAP相關寄存器的任何事情,因此,自然不需要 對 IAP相關寄存器做任何 保護工作。至于具體的 MOVC 讀取時地址這塊的可以詳見 STC8系列的手冊。
回復

使用道具 舉報

77#
ID:227818 發表于 2022-10-6 09:23 | 只看該作者
Y_G_G 發表于 2022-7-19 01:18
你要看的是這一本書,網上應該可以搜索到不要錢的PDF版本,也可以買二手的,馬云家30塊左右,超過這個價錢就 ...

我買回了這本書,正在學習中,謝謝。
回復

使用道具 舉報

78#
ID:227818 發表于 2022-10-6 09:28 | 只看該作者
188610329 發表于 2022-8-7 17:59
STC的 Eeprom 是把 Flash 空間模擬成 Eeprom 來操作,尤其是STC8系列,他在物理上就是 ROM的一部分。所以 ...

好的,您說的,我慢慢理會。這一段時間,正看程序,原程序中bug不少,比如,一個子程序,有時用LCALL調用,當然,這是對的,竟然有時用LJMP跳轉過去,我都不知道最后執行了RET之后去了哪里。
回復

使用道具 舉報

79#
ID:624769 發表于 2022-10-6 15:00 | 只看該作者
newlined 發表于 2022-10-6 09:28
好的,您說的,我慢慢理會。這一段時間,正看程序,原程序中bug不少,比如,一個子程序,有時用LCALL調用 ...

唉…… 這是基礎中的基礎啊……
給你舉個例子吧:
有個函數:
SEND_HALF_BCD:
ANL   A,#0FH
ORL   A,#30H

SEND_BYTE:
JNB     TI,$
CLR     TI
MOV   SBUF,A
RET

你要發送  一個BCD出去, 可以制作這么一個函數:
_Send_BCD:         ;通過R7傳入
MOV   A,R7
SWAP A
LCALL  SEND_HALF_BCD
MOV   A,R7
LCALL  SEND_HALF_BCD

RET
通常, 你覺得應該這么寫對吧? 但是,這么寫其實是完全沒有 用到匯編的優勢 。
所以,既然用了匯編,通常用如下寫法:
_Send_BCD:         ;通過R7傳入
MOV   A,R7
SWAP A
LCALL  SEND_HALF_BCD
MOV   A,R7
LJMP  SEND_HALF_BCD
這樣寫, 就避免了 無意義的 RET。 程序會依然回 到  LCALL  _Send_BCD 的地方。而效率會變高

所以, 你要搞清楚  有時LCALL 有時LJMP, 到底是 BUG  還是你沒理解  程序本身的 真正目的?



回復

使用道具 舉報

80#
ID:227818 發表于 2022-10-25 13:50 | 只看該作者
188610329 發表于 2022-10-6 15:00
唉…… 這是基礎中的基礎啊……
給你舉個例子吧:
有個函數:

你好,這個例子,我一直試圖理解,但我沒有想通。我是這樣理解的,LCALL 一個函數時,堆棧會保存當前調用時的地址,RET 時,這個地址會恢復到PC程序計數器中,如果LJMP到一個函數,堆棧不會保存當前地址,執行到RET時,堆棧里的兩個字節,恢復到PC程序計數器中,這個應該是錯誤的吧。
回復

使用道具 舉報

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

本版積分規則

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

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 男女爱爱福利视频 | www.玖玖玖| 亚洲综合无码一区二区 | 美女张开腿露出尿口 | 黄色小视频入口 | 亚洲品质自拍视频网站 | 日韩综合在线 | 色网站在线 | 亚洲精品久久视频 | 日本成人综合 | 嫩草国产 | 青春草国产 | 国产成人精品福利 | 巨大黑人极品videos精品 | 国产成人精品一区二区三区视频 | 精品亚洲一区二区三区 | 国产精品高清一区二区三区 | 欧美性网| 麻豆久久久久久久 | 一区二区三区亚洲视频 | 国产精品2区 | 日韩欧美国产一区二区三区 | 成人性生交大片免费看r链接 | 精品无码久久久久久国产 | 四虎永久影院 | 91久久精品一区二区二区 | 亚洲午夜精品视频 | 一区二区视频免费观看 | 久草视频在| 一区二区国产精品 | 欧美日韩福利 | japanhdxxxx裸体 | 国产精品久久国产精品 | 日韩欧美精品一区 | 成人在线电影在线观看 | 精品国产乱码久久久久久牛牛 | h片在线免费看 | 一区二区三区影院 | 99久久国产 | 黄色片视频网站 | 不用播放器看的av |