关于相对PC值
请教马老师什么是相对PC值?我不明白跳转指令的确切意义。比如您书中写的:(4)不相等跳转
BRNE k -64≤k≤63
说明:条件相对跳转,测试零标志位Z,如果Z位被清零,则相对PC值跳转k个字。这条指令相当于指令BRBC 1,k
1、文中的K是一个常量(数字),还是一个标号?
2、如果是一个常量,那么岂不是要知道当前PC值到目的PC值得差。
3、如果是一个标号,那是不是限制我当前点到目的点的代码长度。 先明白以下几个基本的概念:
该指令的机器码为:1111 01kk kkkk k000.其中7个k(二进制)就是汇编指令BRNE k中的k所代表的相对跳转偏移量.7位二进制k的范围-64≤k≤63.
因此最原始(或最贴近机器码)的汇编应该如此表示: BRNE 25 (假定相对跳转偏移量为25).也就是说,k必须是个数字(-64≤k≤63)
而现在是使用软件将汇编指令"翻译"成机器代码的,这个"翻译"软件就是汇编系统.在汇编系统平台中,为了方便程序员编写程序,将汇编指令的限制适当放宽了,如允许这样写:LDS Rd,30+50
而原始的 LDS 指令里面不能有加法表达式的.汇编系统如何能允许这样写呢?
汇编系统实际上是先将 30+50 计算好, 然后整理指令为 LDS Rd,80, 然后再将其"翻译"机器码.
能够理解这点的话,下面就能理解了.
1、文中的k是一个常量(数字),还是一个标号?
=====>原始汇编中应该为数字常量,但在汇编系统中扩展了,可以(通常也是)用标号代替.
2、如果是一个常量,那么岂不是要知道当前PC值到目的PC值得差。
=====>采用人工编译的话,就得你搬手指计算出数值了.这样肯定不方便.现在使用软件汇编系统,不需要了,用标号代替吧.
3、如果是一个标号,那是不是限制我当前点到目的点的代码长度。
使用了标号,汇编系统在"翻译"的过程中,会帮你计算从跳转指令到标号处指令之间的偏移量(字数).如果超出范围,编译系统将给出错误提示,告示程序员超出范围,修改代码.如果在范围内,就会将该计算出的数字代替跳转指令中的标号,然后生成相应的机器码. 非常感谢您!马老师。我明白了 请问马老师:程序获取PC值有哪些办法?
===============================================
以前发的贴,但没能得到答案。
目的:实现单片机用的断言assert(),即断言失败时,获取出错程序的PC值,直接显示或串口输出,配合AVR Studio 的仿真能力(汇编窗口)定位出错程序。
目前办法:assert()写成函数,调用时程序自动压栈PC,再通过SP指针读取PC。
各位大虾若有更快捷的办法,敬请赐教!
声明:本人,新手,不会AVR汇编,不知道汇编能不能行,若行的话,能否贴上。
附上简陋的代码,算是抛砖引玉。
#ifdef DEBUG
#define MY_ASSERT(condition) backup_SP = SP;\
my_assert(condition)
volatile unsigned int backup_SP;
void my_assert(unsigned char condition)
{
unsigned int backup_PC;
if(!condition)
{
backup_PC = *(unsigned char *)(backup_SP - 1);
backup_PC <<= 8;
backup_PC += *(unsigned char *)(backup_SP);
//...
//添加出错输出
//...
while(1);
}
return;
}
#else
#define MY_ASSERT(condition) //空定义
#endif 程序计数寄存器PC是个重要的寄存器,一旦破坏,系统肯定崩溃了.因此汇编指令不可以直接对PC操作的,因此要获得PC的值只能通过间接的方法.
通过中断,到堆栈中获得PC的地址是常用的方法,不过得到的不是当前的PC,是响应中断时的PC.
我不明白3楼具体想做什么,好象要设计调试系统.不过,真的像3楼的声明:"本人,新手,不会AVR汇编"那样,那么还是先放一放,等有一定的基础后再做思考.
页:
[1]