1600277881 发表于 2024-3-26 00:17 经过老师们的指点,总是让我有所收获。谢谢!谢谢各位 我将您上文所指的约定,理解为类似 arm 过程调用标准AAPCS。 |
人中狼 发表于 2024-3-25 23:25 您这样描述我感到是的, |
lyonkon 发表于 2024-3-25 21:44 另外51它不是ARM,你子细的研究一下它的指令特性, 会得出这样的一个结论, 使用r0~r7的效率并不高, 除非是在计算中短时间内多次使用的值,把它存于寄存器内会更有效率, 而大部时间都没需要把值mov到寄存器才做运算, 直接地址操作变量就可以了。所以你在二级子程序用了4个寄存器是应该可以优化的。 |
lyonkon 发表于 2024-3-25 21:44 你贴的这代码能跑?这应该是中断服务程式,因为有其中一个退出口是reti, 但奇怪的是出栈的只有ACC, PSW呢? PSW进来时压栈了没有? 如果有压, 那为啥退出前没出栈?如果说PSW进来就没压过栈,那你的代码必定会出问题, 主程序的PSW都被中断服务程式中的CJNE指令改了CY。 |
lyonkon 发表于 2024-3-25 21:44 而中断程序,都是避免使用寄存器,你贴的代码就没必要用到寄存器, 用ACC就足够了, 根本就没必要把寄存器压栈, 只压ACC PSW就足以 |
lyonkon 发表于 2024-3-25 21:44 "因为51单片机R0--R7无法压栈" 51 的r0~r7是可以压栈的, 只不过要写寄存器的地址 比如 r0的地址是 0x00, r1 地址是 0x01 ..... r7 地址是 0x07 所以 push R3, 要写成 push 0x03, 或者 push AR3 AR0。。。AR7 是keil自带的寄存器地址定义 在中断程序把寄存器压栈,一定一定要注意的是限制主程序里只能用到寄存器组0 |
lyonkon 发表于 2024-3-25 21:44 三 如果说中断程序里,差不多R0~R7都用了, 这一般都不会用寄存器入栈的方式,因为它耗废资源大,而会用寄存器组的转换, 比如 using 1 ;//如果你编的是C+汇编的混合编程,需要这句来告诉编译器你用了寄存器组1 push psw mov psw,#0x08 ;//转换至寄存器组1 push acc ..... ;// 这里面就R0~R7 都可以随你用 .... pop psw |
感觉有点想做模块化,规范化,但却连什么是模块化都还不清楚 |
lyonkon 发表于 2024-3-25 21:44 我说话比较直接, 希望你别介意 你对51的性能是非常的不熟悉 进中断服务程序后保存寄存器,都会按以下的思路做的 一, 中断服务程序里,如果说没用到ACC, 没用到R0~R7, 而又没产生PSW的改变(51大部分的指令都不会改变PSW, 比如 inc dec djnz adl xor xrl。。。都不会改变psw的), 就啥也不需要保存。 二, 用到ACC 或 某几个寄存器, 就它们入栈, 寄存器是可以通过其地址入栈的, 比如 push 0x02 ; R2 |
lyonkon 发表于 2024-3-25 21:04 我回复的不是中断程序来的,你子细看看 |
Hephaestus 发表于 2024-3-25 19:46 烦怎么了? 你还没资格评谁半瓶谁全瓶 继续晃, 就是晃 |
1600277881 发表于 2024-3-25 01:06 PUSH ACC是按通常格式写的,PUSH PSW ;SETB PSW.3是中断程序用的,中断程序每次接受8字节数据,存寄存器页面1,收完出中断 恢复 PSW。当子程序用到这8字节数据的时候,再SETB PSW.3。这样值直接从寄存器使用,省的从内存来回调。使用页面,一是为了传值方便,二,当子程序正在操作R0--R7寄存器时,中断来了这时候无法对现有寄存器进行保护,当出中断的时候R0--R7值已经变了,程序就错误运行,达不到目的。 |
1600277881 发表于 2024-3-25 02:17 最烦你这种半瓶醋不满到处乱晃荡的。 |
Hephaestus 发表于 2024-3-25 01:29 你还要去查? ![]() 我是一条指令代替楼主的一个函数。 学51多久了? % |
1600277881 发表于 2024-3-25 01:18 又查了下8051指令集,发现楼主是最正确的,只有1个字节就办完了。 你是最错误的,浪费了一个字节的flash空间,干了跟楼主一样的活儿,% |
Hephaestus 发表于 2024-3-23 18:05 正确?你定来定义正确? 如果说不能一眼就看出地址0x02是啥玩儿, 你还是回去学习学习再回来接我的话吧 |
lyonkon 发表于 2024-3-23 17:53 更深入的就先不讨论, 就PUSH ACC, PUSH PSW而言, 你觉得有需要?函数参数通过什么方式传递, 什么寄存器可以在函数内使用而无需保存数值,这都是有约定的。 ACC 和 PSW 不需要存值, 除非你说我有自己的约定。 你可以自己用C写一个简单的函数,看看有没有保存ACC和PSW的, 一般的中断函数才需要保存ACC和PSW,但也不是一定的。 |
Hephaestus 发表于 2024-3-23 18:05 想必你连AR2是怎样来的也查了一段时间吧? ![]() |
Y_G_G 发表于 2024-3-24 11:06 说的太对了,楼主2年前就开始搞汇编了,到现在就这点儿。 |
TTQ001 发表于 2024-3-24 02:09 有的人对“编程”,“原理”,“理论",”好用“。。。。。。。之类的东西,有着自己固执的理解,一旦人认定了自己的方向是对的,你旁人的建议都是没用的 |
学习汇编语言非常耗时。 为什么不使用C语言呢 |
感谢指点 |
这都是那些不懂装懂的货色写出的破书误导的,前面三个EQU,规范的写法应该是DBIT、DATA、DATA。 |
1600277881 发表于 2024-3-23 02:20 你的汇编需要进步了。正确的写法是: mov @r0,AR2 虽然你写的很不规范,但也能通过编译。 |
1600277881 发表于 2024-3-23 02:45 CJNE对ACC.C的影响,以前讨论过,只是没有实践。参数传递,我现在用的是以下方式。 HCD: PUSH ACC PUSH PSW SETB PSW.3 MOV R0,.... .... .... POP PSW POP ACC RET |
别找书了,一般书的汇编也就刚刚合格的水平,动手把你贴出的这段汇编优化, 很能学会很多。 |
你的汇编还是有很大的进步空间 mov @r0, 0x02 ; R2 的地址==0x02 (Bank 0) |
任何资料和书籍都不会讲。是你自己写的程序,复用程度高的自然就会变成函数以节约flash空间,别人谁知道你脑子怎么想的? |
汇编语言了解一下是必须的,但是绝大部分程序还得用C语言(除非不支持C语言), 因为C语言很方便修改和移植。 哪种芯片价格低就用哪种,这就有了移植的问题。可以设置开关,很方便增减程序 的功能,等等,C语言的好处多了去了。 |
lyonkon 发表于 2024-3-22 21:40 STM32你都弄好了,不需要学习任何知识了。 |
楼主一年前就在学汇编,还是高大上的ARM汇编,然后退回到51,才学了这么一点点? |
你这个很完整了啊,记得push和pop保护用到的寄存器,随便怎么都可以啊 |