函数体外关系操作:跳转(*jmp)

Goto语句,完成函数体内部进行跳转,首先不提倡用,但是当发生错误时的跳转还有有必要的。

但是,我也有在想,那它可以在不同的函数之间跳转吗?当然不可以,那WHO可以呢?

#include<setjmp.h>

Intsetjmp(jmp_buf env);

Intlongjmp(jmp_buf env,int val);

第一次看到这个东西,我快疯了,这是个什么东东。

那是因为,我对函数调用的“栈帧”概念不明白具体是什么所导致的!

现在如果一个程序中包含(很)深层次的函数调用时,从MAIN进入开始就在开栈,而这个栈就会在内存中开辟栈帧(自然会是使用首地址),接着后面的每个函数调用,都会像MAIN一样,形成在内存中的很多栈帧。

Setjmp和longjmp会配合使用,当调用到longjmp,它会返回到setjmp调用的位置,这时候在内存中会将除调用setjmp层函数栈外,其他函数栈帧清空。好了,现在出现很多问题了。

我们调用的函数中,会使用到自动变量,当然这些自动变量的存储只是在每个函数的栈帧中,那如果这个栈帧由于函数的跳转在内存中被清空了,那这些自动变量假设由于某种需求被改变了怎么办?它是继续使用之前的值还是改变之后的呢?!

好吧,现在如果不想使自动变量的值回滚,那就请用volative修饰下吧,告诉“那个谁”我喜欢最新的值(我是一个喜新厌旧的人)。

另外,问题还有一个问题,声明自动变量的函数已经返回,那就不能去引用这些自动变量,那我们就没有办法治它了?有啊,可以有全局存储空间静态地(static、extern修饰)或动态地(前提是数组,使用malloc、calloc、realloc)为其分配空间。

这段汇编代码看起来是一个计时器中断处理程序的一部分。以下是我对代码的解释: 1. `TIME_COUNT_L:` 是一个标签,表示代码的入口点。 2. `CLR WDT` 是清除看门狗定时器的指令,用于防止看门狗复位。 3. `SZ dp1.0` 检查 `dp1.0` 位是否为零(Skip if Zero),如果为零,则跳转到 `START_L` 标签处继续执行;如果不为零,则继续执行后续指令。 4. `SNZ KEY` 检查 `KEY` 变量是否为零(Skip if Not Zero),如果不为零,则跳转到 `SET_VOID` 标签处继续执行;如果为零,则继续执行后续指令。 5. `MOV A, ap0` 将 `ap0` 寄存器的值移动到累加器 `A` 中。 6. `SUB A, 20` 将累加器 `A` 中的值减去 20。 7. `SNZ STATUS.0` 检查状态寄存器 `STATUS` 的第 0 位是否为零(Skip if Not Zero),如果不为零,则跳转到 `LOOP_0` 标签处继续执行;如果为零,则继续执行后续指令。 8. `CLR ap0` 将 `ap0` 寄存器清零。 9. `SET dp1.0` 将 `dp1.0` 位设置为 1。 10. `NOP` 是一个空操作指令,不执行任何操作,用于延迟一段时间。 11. `SET LED_R1` 和 `SET LED_R2` 是设置某些 LED 灯的指令,根据注释中的信息,可能是用来点亮某些红色 LED 灯。 12. `MOV A, 010h` 将立即数 010h 移动到累加器 `A` 中。 13. `MOV bp0, A` 将累加器 `A` 中的值移动到 `bp0` 寄存器中。 请注意,这只是代码的一部分,并且缺少其他指令和上下文信息。如果你有完整的代码或更多的上下文信息,我可以提供更准确的解释和帮助。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值