找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 1238|回复: 35
收起左侧

汇编语言进阶的问题

[复制链接]
ID:73992 发表于 2024-3-22 14:38 | 显示全部楼层 |阅读模式
在写汇编程序过程当中,发现很多时候程序功能重复。比如 某值写入某地址,在整个程序当中可能会多次需要给地址写值的情况。为了将程序简化,使用了下图做法____将经常用到的功能通用化,就是写成子程序。
这样程序看起来简单些。
如果想学一下这部分知识,需要学习哪些内容
无标题.png

回复

使用道具 举报

ID:73992 发表于 2024-3-26 21:26 | 显示全部楼层
1600277881 发表于 2024-3-26 00:17
另外51它不是ARM,你子细的研究一下它的指令特性, 会得出这样的一个结论, 使用r0~r7的效率并不高, 除 ...

经过老师们的指点,总是让我有所收获。谢谢!谢谢各位
我将您上文所指的约定,理解为类似 arm 过程调用标准AAPCS。
回复

使用道具 举报

ID:73992 发表于 2024-3-26 21:23 | 显示全部楼层
人中狼 发表于 2024-3-25 23:25
感觉有点想做模块化,规范化,但却连什么是模块化都还不清楚

您这样描述我感到是的,
回复

使用道具 举报

ID:1088185 发表于 2024-3-26 00:17 | 显示全部楼层
lyonkon 发表于 2024-3-25 21:44
以前,因为寄存器不够用。一种情况是:子程序用了4个寄存器,子程序调用二级子程序又用了超过4个寄存器。 ...

另外51它不是ARM,你子细的研究一下它的指令特性, 会得出这样的一个结论, 使用r0~r7的效率并不高, 除非是在计算中短时间内多次使用的值,把它存于寄存器内会更有效率, 而大部时间都没需要把值mov到寄存器才做运算, 直接地址操作变量就可以了。所以你在二级子程序用了4个寄存器是应该可以优化的。
回复

使用道具 举报

ID:1088185 发表于 2024-3-26 00:02 | 显示全部楼层
lyonkon 发表于 2024-3-25 21:44
以前,因为寄存器不够用。一种情况是:子程序用了4个寄存器,子程序调用二级子程序又用了超过4个寄存器。 ...

你贴的这代码能跑?这应该是中断服务程式,因为有其中一个退出口是reti, 但奇怪的是出栈的只有ACC, PSW呢? PSW进来时压栈了没有? 如果有压, 那为啥退出前没出栈?如果说PSW进来就没压过栈,那你的代码必定会出问题, 主程序的PSW都被中断服务程式中的CJNE指令改了CY。
回复

使用道具 举报

ID:1088185 发表于 2024-3-25 23:52 | 显示全部楼层
lyonkon 发表于 2024-3-25 21:44
以前,因为寄存器不够用。一种情况是:子程序用了4个寄存器,子程序调用二级子程序又用了超过4个寄存器。 ...

而中断程序,都是避免使用寄存器,你贴的代码就没必要用到寄存器, 用ACC就足够了, 根本就没必要把寄存器压栈, 只压ACC PSW就足以
回复

使用道具 举报

ID:1088185 发表于 2024-3-25 23:46 | 显示全部楼层
lyonkon 发表于 2024-3-25 21:44
以前,因为寄存器不够用。一种情况是:子程序用了4个寄存器,子程序调用二级子程序又用了超过4个寄存器。 ...

"因为51单片机R0--R7无法压栈"

51 的r0~r7是可以压栈的, 只不过要写寄存器的地址
比如 r0的地址是 0x00, r1 地址是 0x01 ..... r7 地址是 0x07
所以 push R3, 要写成 push 0x03, 或者 push AR3
AR0。。。AR7 是keil自带的寄存器地址定义
在中断程序把寄存器压栈,一定一定要注意的是限制主程序里只能用到寄存器组0
回复

使用道具 举报

ID:1088185 发表于 2024-3-25 23:31 | 显示全部楼层
lyonkon 发表于 2024-3-25 21:44
以前,因为寄存器不够用。一种情况是:子程序用了4个寄存器,子程序调用二级子程序又用了超过4个寄存器。 ...

三 如果说中断程序里,差不多R0~R7都用了, 这一般都不会用寄存器入栈的方式,因为它耗废资源大,而会用寄存器组的转换,

比如

  using 1     ;//如果你编的是C+汇编的混合编程,需要这句来告诉编译器你用了寄存器组1
push psw
mov  psw,#0x08  ;//转换至寄存器组1
push acc
.....            ;// 这里面就R0~R7 都可以随你用
....

pop  psw
回复

使用道具 举报

ID:384109 发表于 2024-3-25 23:25 | 显示全部楼层
感觉有点想做模块化,规范化,但却连什么是模块化都还不清楚
回复

使用道具 举报

ID:1088185 发表于 2024-3-25 23:21 | 显示全部楼层
lyonkon 发表于 2024-3-25 21:44
以前,因为寄存器不够用。一种情况是:子程序用了4个寄存器,子程序调用二级子程序又用了超过4个寄存器。 ...

我说话比较直接, 希望你别介意
你对51的性能是非常的不熟悉

进中断服务程序后保存寄存器,都会按以下的思路做的
一, 中断服务程序里,如果说没用到ACC, 没用到R0~R7,  而又没产生PSW的改变(51大部分的指令都不会改变PSW, 比如 inc dec djnz adl xor xrl。。。都不会改变psw的), 就啥也不需要保存。
二, 用到ACC 或 某几个寄存器, 就它们入栈, 寄存器是可以通过其地址入栈的, 比如 push 0x02 ; R2
回复

使用道具 举报

ID:1088185 发表于 2024-3-25 23:06 | 显示全部楼层
lyonkon 发表于 2024-3-25 21:04
PUSH ACC是按通常格式写的,PUSH PSW ;SETB PSW.3是中断程序用的,中断程序每次接受8字节数据,存寄存器 ...

我回复的不是中断程序来的,你子细看看
回复

使用道具 举报

ID:1088185 发表于 2024-3-25 23:02 | 显示全部楼层
Hephaestus 发表于 2024-3-25 19:46
最烦你这种半瓶醋不满到处乱晃荡的。

烦怎么了?
你还没资格评谁半瓶谁全瓶
继续晃, 就是晃
回复

使用道具 举报

ID:73992 发表于 2024-3-25 21:44 | 显示全部楼层
1600277881 发表于 2024-3-25 01:06
更深入的就先不讨论, 就PUSH ACC, PUSH PSW而言, 你觉得有需要?函数参数通过什么方式传递, 什么寄存 ...

以前,因为寄存器不够用。一种情况是:子程序用了4个寄存器,子程序调用二级子程序又用了超过4个寄存器。二级子程序调用第三级子程序的时候寄存器就没有寄存器用了.记得是写12864显示程序遇到过这种情况。
  第二种情况也类似,子程序调用另外的子程序,寄存器就不够用了。
因为51单片机R0--R7无法压栈,当时就用了下图方案。“”手动压栈“”。
6666.png 777777.png

学会R0--R7分页操作,寄存器基本够用。
回复

使用道具 举报

ID:73992 发表于 2024-3-25 21:04 | 显示全部楼层
1600277881 发表于 2024-3-25 01:06
更深入的就先不讨论, 就PUSH ACC, PUSH PSW而言, 你觉得有需要?函数参数通过什么方式传递, 什么寄存 ...

PUSH ACC是按通常格式写的,PUSH PSW ;SETB PSW.3是中断程序用的,中断程序每次接受8字节数据,存寄存器页面1,收完出中断 恢复 PSW。当子程序用到这8字节数据的时候,再SETB PSW.3。这样值直接从寄存器使用,省的从内存来回调。使用页面,一是为了传值方便,二,当子程序正在操作R0--R7寄存器时,中断来了这时候无法对现有寄存器进行保护,当出中断的时候R0--R7值已经变了,程序就错误运行,达不到目的。
回复

使用道具 举报

ID:883242 发表于 2024-3-25 19:46 | 显示全部楼层
1600277881 发表于 2024-3-25 02:17
你还要去查?
我是一条指令代替楼主的一个函数。
学51多久了?

最烦你这种半瓶醋不满到处乱晃荡的。
回复

使用道具 举报

ID:1088185 发表于 2024-3-25 02:17 | 显示全部楼层
Hephaestus 发表于 2024-3-25 01:29
又查了下8051指令集,发现楼主是最正确的,只有1个字节就办完了。

你是最错误的,浪费了一个字节的fla ...

你还要去查?
我是一条指令代替楼主的一个函数。
学51多久了?
%
回复

使用道具 举报

ID:883242 发表于 2024-3-25 01:29 | 显示全部楼层
1600277881 发表于 2024-3-25 01:18
正确?你定来定义正确?
如果说不能一眼就看出地址0x02是啥玩儿, 你还是回去学习学习再回来接我的话吧

又查了下8051指令集,发现楼主是最正确的,只有1个字节就办完了。

你是最错误的,浪费了一个字节的flash空间,干了跟楼主一样的活儿,%
回复

使用道具 举报

ID:1088185 发表于 2024-3-25 01:18 | 显示全部楼层
Hephaestus 发表于 2024-3-23 18:05
你的汇编需要进步了。正确的写法是:
mov @r0,AR2

正确?你定来定义正确?
如果说不能一眼就看出地址0x02是啥玩儿, 你还是回去学习学习再回来接我的话吧
回复

使用道具 举报

ID:1088185 发表于 2024-3-25 01:06 | 显示全部楼层
lyonkon 发表于 2024-3-23 17:53
CJNE对ACC.C的影响,以前讨论过,只是没有实践。参数传递,我现在用的是以下方式。
HCD:
       PUSH A ...

更深入的就先不讨论, 就PUSH ACC, PUSH PSW而言, 你觉得有需要?函数参数通过什么方式传递, 什么寄存器可以在函数内使用而无需保存数值,这都是有约定的。
ACC 和 PSW 不需要存值, 除非你说我有自己的约定。
你可以自己用C写一个简单的函数,看看有没有保存ACC和PSW的, 一般的中断函数才需要保存ACC和PSW,但也不是一定的。
回复

使用道具 举报

ID:1088185 发表于 2024-3-25 00:57 | 显示全部楼层
Hephaestus 发表于 2024-3-23 18:05
你的汇编需要进步了。正确的写法是:
mov @r0,AR2

想必你连AR2是怎样来的也查了一段时间吧?
回复

使用道具 举报

ID:883242 发表于 2024-3-24 17:15 | 显示全部楼层
Y_G_G 发表于 2024-3-24 11:06
有的人对“编程”,“原理”,“理论",”好用“。。。。。。。之类的东西,有着自己固执的理解,一旦人 ...

说的太对了,楼主2年前就开始搞汇编了,到现在就这点儿。
回复

使用道具 举报

ID:401564 发表于 2024-3-24 11:06 | 显示全部楼层
TTQ001 发表于 2024-3-24 02:09
学习汇编语言非常耗时。 为什么不使用C语言呢

有的人对“编程”,“原理”,“理论",”好用“。。。。。。。之类的东西,有着自己固执的理解,一旦人认定了自己的方向是对的,你旁人的建议都是没用的
回复

使用道具 举报

ID:420836 发表于 2024-3-24 02:09 | 显示全部楼层
学习汇编语言非常耗时。 为什么不使用C语言呢
回复

使用道具 举报

ID:73992 发表于 2024-3-23 20:13 | 显示全部楼层

感谢指点
回复

使用道具 举报

ID:883242 发表于 2024-3-23 18:06 | 显示全部楼层

这都是那些不懂装懂的货色写出的破书误导的,前面三个EQU,规范的写法应该是DBIT、DATA、DATA。
回复

使用道具 举报

ID:883242 发表于 2024-3-23 18:05 | 显示全部楼层
1600277881 发表于 2024-3-23 02:20
你的汇编还是有很大的进步空间

mov   @r0, 0x02    ; R2 的地址==0x02 (Bank 0)

你的汇编需要进步了。正确的写法是:
mov @r0,AR2

虽然你写的很不规范,但也能通过编译。
回复

使用道具 举报

ID:73992 发表于 2024-3-23 17:53 | 显示全部楼层
1600277881 发表于 2024-3-23 02:45
别找书了,一般书的汇编也就刚刚合格的水平,动手把你贴出的这段汇编优化, 很能学会很多。

CJNE对ACC.C的影响,以前讨论过,只是没有实践。参数传递,我现在用的是以下方式。
HCD:
       PUSH ACC
       PUSH PSW
       SETB PSW.3
       MOV R0,....
       ....   ....
       POP PSW
       POP ACC
       RET
回复

使用道具 举报

ID:1088185 发表于 2024-3-23 02:45 | 显示全部楼层

别找书了,一般书的汇编也就刚刚合格的水平,动手把你贴出的这段汇编优化, 很能学会很多。
回复

使用道具 举报

ID:1088185 发表于 2024-3-23 02:20 | 显示全部楼层
你的汇编还是有很大的进步空间

mov   @r0, 0x02    ; R2 的地址==0x02 (Bank 0)

回复

使用道具 举报

ID:883242 发表于 2024-3-22 23:45 | 显示全部楼层

任何资料和书籍都不会讲。是你自己写的程序,复用程度高的自然就会变成函数以节约flash空间,别人谁知道你脑子怎么想的?
回复

使用道具 举报

ID:73992 发表于 2024-3-22 23:12 | 显示全部楼层
祥子陈 发表于 2024-3-22 20:31
你这个很完整了啊,记得push和pop保护用到的寄存器,随便怎么都可以啊

5555.png
回复

使用道具 举报

ID:1110945 发表于 2024-3-22 22:56 | 显示全部楼层
汇编语言了解一下是必须的,但是绝大部分程序还得用C语言(除非不支持C语言),
因为C语言很方便修改和移植。
哪种芯片价格低就用哪种,这就有了移植的问题。可以设置开关,很方便增减程序
的功能,等等,C语言的好处多了去了。
回复

使用道具 举报

ID:883242 发表于 2024-3-22 22:19 | 显示全部楼层
lyonkon 发表于 2024-3-22 21:40
使用51是为了增加键盘驱动。主板输入/输出显示 写差不多了,文本编辑是最基本的功能。但是文本编辑器目前 ...

STM32你都弄好了,不需要学习任何知识了。
回复

使用道具 举报

ID:73992 发表于 2024-3-22 21:40 | 显示全部楼层
Hephaestus 发表于 2024-3-22 20:39
楼主一年前就在学汇编,还是高大上的ARM汇编,然后退回到51,才学了这么一点点?

使用51单片机是为了增加键盘驱动。主板输入/输出显示 写差不多了,文本编辑是最基本的功能。但是文本编辑器目前没有思路。在增加程序功能之前,我想把现有程序优化一下,为以后容易看懂和修改。就以51单片机汇编为例,以程序块方式优化一下程序。在同一个程序中,使用通用程序块,修改,阅读,都方便 还可以降低代码量。
我的问题是,设计更多的通用程序块 需要学习哪一部分知识。

无标题2.png


回复

使用道具 举报

ID:883242 发表于 2024-3-22 20:39 | 显示全部楼层
楼主一年前就在学汇编,还是高大上的ARM汇编,然后退回到51,才学了这么一点点?
回复

使用道具 举报

ID:235438 发表于 2024-3-22 20:31 | 显示全部楼层
你这个很完整了啊,记得push和pop保护用到的寄存器,随便怎么都可以啊
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表