找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
123
返回列表 发新帖
楼主: newlined
打印 上一主题 下一主题
收起左侧

请教各位大神一个汇编语言堆栈大小计算的问题

[复制链接]
81#
ID:624769 发表于 2022-10-25 14:38 | 只看该作者
newlined 发表于 2022-10-25 13:50
你好,这个例子,我一直试图理解,但我没有想通。我是这样理解的,LCALL 一个函数时,堆栈会保存当前调用 ...

CALL 一次,就会把当前地址放入  栈   然后跳转,读到RET  从 栈里 读出地址, 然后返回  CALL 的地方。
回复

使用道具 举报

82#
ID:384109 发表于 2022-10-25 14:43 | 只看该作者
lcall和ljmp是不同的机制,lcall会压栈,ljmp不对栈操作,lcal必须有ret,ljmp一定不能有ret,51除了硬件自动压栈的以外,其他都是人工压栈的
回复

使用道具 举报

83#
ID:624769 发表于 2022-10-25 14:58 | 只看该作者
newlined 发表于 2022-10-25 13:50
你好,这个例子,我一直试图理解,但我没有想通。我是这样理解的,LCALL 一个函数时,堆栈会保存当前调用 ...

CALL 一次  就会把地址  存入栈  然后  跳转执行, 运行到 RET 就会从 栈中取出 地址, 返回CALL 的地方。
CALL 和 RET  应该是 成对的关系。没错吧? C 就是这么做的。

然后,你 CALL 一个函数, 这个函数,里面还要 调用 另一个函数,  
这个时候,应该  CALL  然后, CALL  然后 RET  然后 RET  返回最初的地方对不对?
那么,我简单点,不要CALL 直接JMP可以么?  CALL   JMP   RET  是不是结果一样?

再举个简单的例子吧

就是我之前举的那个例子:

SEND_HALF_BCD:
ANL   A,#0FH
ORL   A,#30H
SEND_BYTE:
JNB     TI,$
CLR     TI
MOV   SBUF,A
RET

这是一个复合函数,

CALL SEND_HALF_BCD  就能把 半个BCD 转成 ASCCII 发出去。
CALL SEND_BYTE      就能直接把 一个字节 发出去,这个能理解么?

到这里为止,是不是没有问题? 能理解么?  能的话,我们往下看。

换个写法:
SEND_HALF_BCD:
ANL   A,#0FH
ORL   A,#30H
CALL        SEND_BYTE
RET

SEND_BYTE:
JNB     TI,$
CLR     TI
MOV   SBUF,A
RET

这样,彻底拆成两个函数,你能看明白么?  
作用和刚才一样,这是纯C的写法。 你比较喜欢这样写是么?
此时如果 CALL SEND_HALF_BCD
这就是你认为应该的, 两次CALL 两次RET 对吧?


然后,我们再换个写法:

SEND_BYTE:
JNB     TI,$
CLR     TI
MOV   SBUF,A
RET

SEND_HALF_BCD:
ANL   A,#0FH
ORL   A,#30H
LJMP SEND_BYTE

这样, CALL SEND_HALF_BCD   有没有问题?  假如你说有问题……  那么,我们换个个。

SEND_HALF_BCD:
ANL   A,#0FH
ORL   A,#30H
LJMP SEND_BYTE

SEND_BYTE:
JNB     TI,$
CLR     TI
MOV   SBUF,A
RET

这样总没问题了吧?

汇编之所以比C 效率高,就是可以避免无意义的  RET。 节约非必要的 RET 是提高效率的一种必要手段。这真的是基础中的基础了……
回复

使用道具 举报

84#
ID:384109 发表于 2022-10-25 15:17 | 只看该作者
楼上的例子有点特例了,像send_byte可以作为一个公用的子程序,如果用jmp,ret会不好控制,除非只有一个地方专门调用,即使是汇编,最好也是模块话,条理会清晰很多
回复

使用道具 举报

85#
ID:883242 发表于 2022-10-25 18:44 | 只看该作者
188610329 发表于 2022-10-25 14:58
CALL 一次  就会把地址  存入栈  然后  跳转执行, 运行到 RET 就会从 栈中取出 地址, 返回CALL 的地方。 ...
  1. %*DEFINE(SEND_BYTE)(
  2.     JNB     TI,$
  3.     CLR     TI
  4.     MOV   SBUF,A
  5. )
  6. SEND_HALF_BCD:
  7.     ANL   A,#0FH
  8.     ORL   A,#30H
  9.     %SEND_BYTE       
复制代码


我这个效率比你的还要高,连LJMP都省掉了,你的汇编还没学到家。

我用的是Intel MCS-51 MACRO ASSEMBLER, V2.2,如果用Keil A51编译不通过请查手册。
回复

使用道具 举报

86#
ID:624769 发表于 2022-10-25 19:45 | 只看该作者
Hephaestus 发表于 2022-10-25 18:44
我这个效率比你的还要高,连LJMP都省掉了,你的汇编还没学到家。

我用的是Intel MCS-51 MACRO ASS ...

人家问 CALL 和 RET,  你发个 没CALL 没 RET 的 代码
回复

使用道具 举报

87#
ID:227818 发表于 2022-10-26 02:20 | 只看该作者
Hephaestus 发表于 2022-10-25 18:44
我这个效率比你的还要高,连LJMP都省掉了,你的汇编还没学到家。

我用的是Intel MCS-51 MACRO ASS ...

您这个看起来更简单,俗话说人外有人,天外有天,但我现在是更看不懂,感谢大家提供不同的代码让我们这些初学者揣摩。
回复

使用道具 举报

88#
ID:883242 发表于 2022-10-26 03:38 | 只看该作者
newlined 发表于 2022-10-26 02:20
您这个看起来更简单,俗话说人外有人,天外有天,但我现在是更看不懂,感谢大家提供不同的代码让我 ...

这不是“人外有人,天外有天”的问题,时间久了你就能明白最重要的学问是数学和英语。
回复

使用道具 举报

89#
ID:624769 发表于 2022-10-26 20:02 | 只看该作者
Hephaestus 发表于 2022-10-26 03:38
这不是“人外有人,天外有天”的问题,时间久了你就能明白最重要的学问是数学和英语。

数一数你这编译出来多少字节, 在来讲话
先不说人家问的  CALL RET , 你 CALL 和 RET 呢?  忘带了?
其次, define 到底是什么? 你应该很清楚,没必要再这里%。
你怎么不把所有代码  define 只后,你还能 只要一句代码  就能把智能蔽障小车写出来呢?
%
回复

使用道具 举报

90#
ID:883242 发表于 2022-10-26 20:18 | 只看该作者
188610329 发表于 2022-10-26 20:02
所以,先把数学学好, 数一数你这编译出来多少字节, 在来讲话, 然后把语文学好,学学怎么讲话。
先不 ...

教你一句成语——不屑一顾。
回复

使用道具 举报

91#
ID:624769 发表于 2022-10-27 00:20 | 只看该作者
Hephaestus 发表于 2022-10-26 20:18
教你一句成语——不屑一顾。

教你一句成语——夜郎自大。
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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