打印
[PIC®/AVR®/dsPIC®产品]

请教AVR程序跳转相关的汇编指令的问题

[复制链接]
1817|3
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
laocuo1142|  楼主 | 2021-10-26 10:52 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 pzsh 于 2021-10-26 18:48 编辑

最近在弄AVR的汇编,遇到了些问题,麻烦热心的网友帮忙看看是怎么回事。

手上的开发板是atmega128a,编译环境是IAR FOR AVR 5.40,仿真器是jtagice。用C编写的代码可以正常编译通过、下载、调试。
用io驱动led,使用定时器中断等都是没有问题的。

阅读了atmega128a的datasheet和8位avr汇编指令的手册,都是atmel官方的。
但是在学习汇编指令时遇到了问题,以下是具体描述:

首先是call指令的问题。
在调试窗口下记录了以下信息:
PC = 0x000FE;//不知道为什么不是16位的,多1个零,很奇怪。先不管,接着往下看。
SP = 0x013D;
当前栈中的数据如下:
(0x013F) = 0x92;(0x013E) = 0x02;(0x013D) = 0xE0;(0x013C) = 0x02;(0x013B) = 0xAE;(0x013A) = 0x02;

CALL function后:
跳转到对应的function中,没问题。然后栈中,(0x013D) = 0x81;(0x013C) = 0x00;
PC = 0x00138;
SP = 0x013B;

在官方手册中看了CALL的描述,操作流程是:
1).把PC + 2 这个值保存到STACK中
2) .SP = SP -2
3). 目标地址写入PC中,程序跳转

因为AVR的栈是空递减的栈,所以,应该是(0x013D,0x013C) = 0x000FE + 2 = 0x00100;
不知道是(0x013D) = 0x00,(0x013C) = 0x01;还是(0x013D) = 0x01,(0x013C) = 0x00;//其实最开始就是为了研究这个问题的,结果却发现了一堆子问题。
手册真不给力,找了半天没找到,干脆就直接在调试环境下自己验证了,没想到卡在这些问题上了。

而现在的实际情况是SP = 0x013B,这个是没问题的,之前的0x013D - 2 = 0x013B。
但是这个栈里面的0x00 ,0x81就不知道是怎么出来的,根本就没见到0x0100的影子,0x00,0x81到底是怎么冒出来的。
可恨的是,后面插入RETI指令,它居然还能正常返回到之前那个函数的下一句。
这说明0x00,0x81是没问题的,另外,CALL和RETI对栈中PC的存取是对应的,不然就不会正常返回。所以我只需要研究其中一种就知道另一种的顺序了。

RETI的就不列举了。

使用特权

评论回复
沙发
pzsh| | 2021-10-26 18:48 | 只看该作者
请熟悉AVR汇编的高手来帮助哈

使用特权

评论回复
板凳
lcczg| | 2021-10-27 17:32 | 只看该作者
跳转处的反汇编代码贴一下,STACK内容变化也贴一下图。

使用特权

评论回复
地板
MianQi| | 2021-10-27 21:46 | 只看该作者
本帖最后由 MianQi 于 2021-10-27 21:48 编辑

1、试一下 Atmel Studio, 那里有详细完整的反汇编窗口和栈窗口。Atmel Studio 到版本7以后就改为Microchip Studio了,如果找不到Atmel Studio就试一下Microchip Studio。说到汇编和栈的事情,还是看看芯片厂家自己的IDE。
2、你看的两个手册的链接是什么,发上来看看。
3、你的C代码粘上来看看。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

1219

主题

5431

帖子

12

粉丝