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

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 1933|回復: 14
收起左側

51單片機匯編語言sp的問題

[復制鏈接]
ID:73992 發表于 2024-5-28 09:01 | 顯示全部樓層 |閱讀模式
請問這種程序結構是否合理。
程序結果不正確。


                ORG        0000H
                LJMP        MAIN


MAIN:
                MOV        SP,#0X30
                LCALL        HBHB
                JMP        MAIN

HBHB:
                PUSH        ACC

                MOV        ACC,#0X01         ;1
                PUSH        ACC

                MOV        ACC,#0X02         ;2
                PUSH        ACC

                MOV        ACC,#0X03         ;3
                PUSH        ACC

                MOV        ACC,#0X04         ;4
                PUSH        ACC

                MOV        ACC,#0X05         ;5
                PUSH        ACC

                MOV        ACC,#0X06         ;6


                MOV        R0,SP                 ;R0保存棧頂
                LCALL        AFAF

                POP        ACC
AFAF:
                PUSH        ACC
                PUSH        SP
                MOV        SP,R0                ;R0釋放棧頂

                POP        ACC                        ;6
                MOV        R1,ACC

                POP        ACC                        ;5
                MOV        R2,ACC

                POP        ACC                        ;4
                MOV        R3,ACC

                POP        ACC                        ;3
                MOV        R4,ACC

                POP        ACC                        ;2
                MOV        R5,ACC

                POP        ACC                        ;1
                MOV        R6,ACC


                PUSH        SP
                POP        ACC
                RET

                END

下是仿真結果
無標題.png


回復

使用道具 舉報

ID:404160 發表于 2024-5-28 10:27 | 顯示全部樓層
  MOV        SP,#0X30這句把程序指針指向了51內部設定的“中斷矢量區。一般是把SP賦值為100
回復

使用道具 舉報

ID:73992 發表于 2024-5-28 11:02 | 顯示全部樓層
飛云居士 發表于 2024-5-28 10:27
MOV        SP,#0X30這句把程序指針指向了51內部設定的“中斷矢量區。一般是把SP賦值為100

sp是棧指針,指向128字節內存地址。
您說的是PC程序計數器
回復

使用道具 舉報

ID:384109 發表于 2024-5-28 12:40 | 顯示全部樓層
先搞懂什么是SP吧
回復

使用道具 舉報

ID:858964 發表于 2024-5-28 13:18 | 顯示全部樓層
MOV   R0,SP  ;R0保存棧頂
...
MOV   SP,R0  ;R0釋放棧頂
這2條指令,保存/釋放棧頂指針,無用。
因為棧頂指針隨著每次進/出棧作用自動改變。

建議改為:
保存/釋放棧項數據,而不是保存/釋放棧項指針。
回復

使用道具 舉報

ID:624769 發表于 2024-5-28 17:10 | 顯示全部樓層
莫名其妙的代碼,也不知道到底要干什么,你這么玩SP 不會直接用 R0 指針操作么?反正,最后你是要把指針放到R0保存,還不如直接用R0了……
回復

使用道具 舉報

ID:123289 發表于 2024-5-29 15:29 | 顯示全部樓層
有此問,說明你對51的指令系統未作認真研讀:
1、LCALL nn
指令執行:PC = nn
再:(SP+2)=(PC+3)H,(SP+1)=(PC+3)L,SP=SP+2

2、RET
指令執行:PC=(SP)(SP-1)
再:SP=SP-2

3、PUSH (R)
指令執行:(SP)=(R)
再:SP=SP+1

4、POP (R)
指令執行:SP=SP-1
再:(R)=(SP-1)

(R):特地加了個(),目的:告訴你,這是R指向的地址中的內容。
(SP-1):特地加了個(),目的:告訴你,這是SP-1指向的地址中的內容。

據此,你自行分析程序是否混亂。混亂的主要表現是:RET回不到原先CALL的下一條指令。
建議研讀指令系統,51系統也就255個,且許多是類同的。
搞匯編,必須讀通讀透指令系統。
任何一款單片機,只要你讀通了它的指令系統,則它的功能就被你掌握了!!! 也可以說,基本了解了一款新的單片機。不信你試試研讀PIC的單片機的指令系統。
回復

使用道具 舉報

ID:123289 發表于 2024-5-30 09:22 | 顯示全部樓層
SP的位置在81H,是個8位的內部寄存器,通常用于做堆棧指針,指針范圍0-255。由于51的堆棧用的是內部寄存器,它只有128或256個字節,所以夠用了。
在高級特殊運用中,可以利用SP進行程序重定位,從而增加反匯編破譯程序的難度。
回復

使用道具 舉報

ID:73992 發表于 2024-5-30 17:57 | 顯示全部樓層
yzwzfyz 發表于 2024-5-30 09:22
SP的位置在81H,是個8位的內部寄存器,通常用于做堆棧指針,指針范圍0-255。由于51的堆棧用的是內部寄存器 ...

感謝老哥慷慨!這種玩法比較飄逸,適合整點花活。感謝!
                ORG        0000H
                LJMP        MAIN
MAIN:
                MOV        SP,#0X30
                LCALL        HBHB
                JMP        MAIN
HBHB:
                PUSH        ACC
                MOV        ACC,#0X01         ;1
                PUSH        ACC
                MOV        ACC,#0X02         ;2
                PUSH        ACC
                MOV        ACC,#0X03         ;3
                PUSH        ACC
                MOV        ACC,#0X04         ;4
                PUSH        ACC
                MOV        ACC,#0X05         ;5
                PUSH        ACC
                MOV        ACC,#0X06         ;6
                PUSH        ACC
                MOV        R0,SP                 ;R0保存棧頂
                LCALL        AFAF

                MOV        A,#0X30                 ;PC返回
                ADD        A,#0X03
                MOV        SP,A
                POP        ACC
                RET
AFAF:
                PUSH        ACC
                MOV        SP,R0                ;R0釋放棧頂
                POP        ACC                        ;6
                MOV        R1,ACC
                POP        ACC                        ;5
                MOV        R2,ACC
                POP        ACC                        ;4
                MOV        R3,ACC
                POP        ACC                        ;3
                MOV        R4,ACC
                POP        ACC                        ;2
                MOV        R5,ACC
                POP        ACC                        ;1
                MOV        R6,ACC

                MOV        A,R0                ;
                ADD        A,#0X03                ;PC返回
                MOV        SP,A
                POP        ACC
                RET

                END
回復

使用道具 舉報

ID:73992 發表于 2024-5-30 21:13 | 顯示全部樓層
188610329 發表于 2024-5-28 17:10
莫名其妙的代碼,也不知道到底要干什么,閼餉賜鍿P 不會直接用 R0 指針操作么?反正,最后你是要把指針放 ...

址應用場景有細微的不同,
回復

使用道具 舉報

ID:879809 發表于 2024-5-30 22:01 | 顯示全部樓層
               POP        ACC                        ;6
                MOV        R1,ACC
用一句話就行了
               POP        AR1                        ;6

這匯編學的也太水了。
回復

使用道具 舉報

ID:73992 發表于 2024-6-2 23:35 | 顯示全部樓層
yzwzfyz 發表于 2024-5-30 09:22
SP的位置在81H,是個8位的內部寄存器,通常用于做堆棧指針,指針范圍0-255。由于51的堆棧用的是內部寄存器 ...

以下是移植到stm32的程序,寫這個程序用了4天。前兩天處理32變磚,后兩天迷茫直到最后才調試出來。
“棧傳遞參數”一年多之前就有需求。在諸多朋友和老哥的指導下,直到現在才解決
;棧傳參數測試        stm32
        AREA        DATA,CODE,READONLY
               
                                AREA        MASTER,CODE,READONLY
                                EXPORT        __main
                                ENTRY
               
__main

GG        BL        CCDE             ;調用CCDE
        B        GG


CCDE
        PUSH        {R4-R11,LR}
        MOV        R0,SP                        ;保存該程序棧
       
        LDR        R4,=0X11111111        ;數據壓入棧A
        PUSH        {R4}
        LDR        R5,=0X22222222
        PUSH        {R5}
        LDR        R6,=0X33333333
        PUSH        {R6}
        LDR        R7,=0X44444444
        PUSH        {R7}
        LDR        R8,=0X55555555
        PUSH        {R8}
        LDR        R9,=0X66666666
        PUSH        {R9}
        LDR        R10,=0X77777777
        PUSH        {R10}
        LDR        R11,=0X88888888
        PUSH        {R11}
               
        MOV        R1,SP                        ;保存棧頂A
       
        BL        CCEF                        ;調用CCEF
       
        MOV        SP,R0                        ;恢復該程序棧
        POP                {R4-R11,LR}
        BX        LR
       
CCEF
        PUSH        {R4-R11,LR}
        MOV        R2,SP                        ;保存該程序棧
       
        MOV        SP,R1                        ;指向棧A
        POP        {R4}                ;取A棧值
        POP        {R5}
        POP        {R6}                ;取A棧值
        POP        {R7}
        POP        {R8}                ;取A棧值
        POP        {R9}
        POP        {R10}                ;取A棧值
        POP        {R11}
       
        MOV        SP,R2                        ;恢復該程序棧
        POP        {R4-R11,LR}
        BX        LR
       
        END

無標題.png

回復

使用道具 舉報

ID:879809 發表于 2024-6-3 21:22 | 顯示全部樓層
ARM函數調用有現成的應用程序二進制接口 (ABI) 規約,R0/R1是參數/結果寄存器,R2/R3是參數寄存器,如果有更多的入口參數才需要壓棧。我就不懂你學了兩年ARM匯編,還在搞這種重復發明輪子的無聊工作,而且你的輪子遠遠沒有現成的標準輪子好用,除了浪費你的生命還有何等意義?
回復

使用道具 舉報

ID:73992 發表于 2024-6-4 21:25 | 顯示全部樓層
rundstedt 發表于 2024-6-3 21:22
ARM函數調用有現成的應用程序二進制接口 (ABI) 規約,R0/R1是參數/結果寄存器,R2/R3是參數寄存器,如果有 ...

程序需要對70多只引腳進行設置,寄存器直接賦值不易修改,也不不易檢查。
單引腳賦值,一個LTORG又不夠,超范圍了。
因為引腳設置程序重復度高,所以用這種方法。用R0至R3傳sp參數,確實是偷懶了,會盡量修改。
我很期望能有老師糾正我寫的程序,程序之間的結構,寫法等等,不然進步太慢。以下是部分程序,
  您提到的造輪子,三言兩語不知道怎么回答。 無標題.png 無標題1.png

回復

使用道具 舉報

ID:57657 發表于 2024-6-4 21:32 | 顯示全部樓層
51單片機的SP是個堆棧寄存器,PUSH/POP/CALL/RET/RETI等指令、中斷觸發都會改變該寄存器的值,具體見數據手冊。
回復

使用道具 舉報

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

本版積分規則

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

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 国产精品精品 | 午夜av影院 | 国产精品成人在线观看 | 国产精品久久亚洲 | 亚洲444kkkk在线观看最新 | 亚洲精品丝袜日韩 | 精品日韩一区 | 久久9999久久 | 天天天天操 | av中文在线观看 | 精品视频一区二区三区在线观看 | 国产成人免费一区二区60岁 | 国产精品美女久久久久aⅴ国产馆 | 日本特黄a级高清免费大片 特黄色一级毛片 | 日韩理论电影在线观看 | 欧美日韩高清 | 五月婷婷激情网 | 激情a| 99久久精品免费看国产四区 | 欧美日一区 | 国产激情视频在线 | 一区二区三区四区视频 | 日韩中文字幕视频在线观看 | 国产精品一区在线观看你懂的 | 亚洲国产成人精品久久 | 欧美精品一区二区三区视频 | 亚洲不卡视频 | 国产一级免费视频 | 欧美成人h版在线观看 | 蜜桃视频一区二区三区 | 亚洲一区成人 | 日本一区二区不卡 | 宅男伊人 | 婷婷二区 | 久久一区二区三区四区 | 国产成人精品免高潮在线观看 | 成年人网站在线观看视频 | 91久久爽久久爽爽久久片 | 97综合在线 | 成人av网站在线观看 | 国产婷婷 |