| 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 |