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 是提高效率的一种必要手段。这真的是基础中的基础了……
|