![]() |
51單片機的SP是個堆棧寄存器,PUSH/POP/CALL/RET/RETI等指令、中斷觸發都會改變該寄存器的值,具體見數據手冊。 |
ARM函數調用有現成的應用程序二進制接口 (ABI) 規約,R0/R1是參數/結果寄存器,R2/R3是參數寄存器,如果有更多的入口參數才需要壓棧。我就不懂你學了兩年ARM匯編,還在搞這種重復發明輪子的無聊工作,而且你的輪子遠遠沒有現成的標準輪子好用,除了浪費你的生命還有何等意義? |
POP ACC ;6 MOV R1,ACC 用一句話就行了 POP AR1 ;6 這匯編學的也太水了。 |
188610329 發表于 2024-5-28 17:10 址應用場景有細微的不同, |
yzwzfyz 發表于 2024-5-30 09:22 感謝老哥慷慨!這種玩法比較飄逸,適合整點花活。感謝!! 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 |
SP的位置在81H,是個8位的內部寄存器,通常用于做堆棧指針,指針范圍0-255。由于51的堆棧用的是內部寄存器,它只有128或256個字節,所以夠用了。 在高級特殊運用中,可以利用SP進行程序重定位,從而增加反匯編破譯程序的難度。 |
有此問,說明你對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的單片機的指令系統。 |
莫名其妙的代碼,也不知道到底要干什么,你這么玩SP 不會直接用 R0 指針操作么?反正,最后你是要把指針放到R0保存,還不如直接用R0了…… |
MOV R0,SP ;R0保存棧頂 ... MOV SP,R0 ;R0釋放棧頂 這2條指令,保存/釋放棧頂指針,無用。 因為棧頂指針隨著每次進/出棧作用自動改變。 建議改為: 保存/釋放棧項數據,而不是保存/釋放棧項指針。 |
先搞懂什么是SP吧 |
飛云居士 發表于 2024-5-28 10:27 sp是棧指針,指向128字節內存地址。 您說的是PC程序計數器 |
MOV SP,#0X30這句把程序指針指向了51內部設定的“中斷矢量區。一般是把SP賦值為100 |