用的是纯汇编,新手学习现在是依葫芦画瓢,就是想把各个环节给弄明白了。
第一个问题我查出来了,因为程序里用到了ser这个置位寄存器指令,而它能置位的区间只能是r16 ~r31,所以如果定义r16之前的寄存器,后边再使用ser这个指令就会提示错误(有些指令只能用在r16 ~r31,自己没注意)。
第二个问题现在只找到出来部分原因,就是AVR的压栈是从SAM的最高位(0x045F)开始从上往下的,如果不配置SP指针寄存器默认是从0xFFFF开始的。
我的程序是:(新手学的秒闪烁器,从AVR单片机嵌入式系统原理与应用第一个程序照搬过来的,调试的时候加了些自己的想法)
.include"m16def.inc"
.def temp1=r17// 定义通用寄存器r20用符号名(变量名)temp1来代替
.org $0000//代码段起始地址
jmp reset//系统上电复位,跳转到主程序
//中断向量区
.org $002A//代码段定位,同时跳过中断向量区,中断向量区:$0000~$0028,21个中断向量,每个中断向量占2个字
reset:
ldi r16,high(RAMEND)//取RAMEND的高位字节,LDI指令只能让一个8位立即数传送到数据寄存器R16~R31中
out sph,r16 //将RAMEND的高位字节送堆栈寄存器SP的高位字节中
ldi r16,low(RAMEND) //取RAMEND的高位字节
out spl,r16 //将RAMEND的高位字节送堆栈寄存器SP的高位字节中
ser temp1 //将temper1(r20)置0xff
out ddrc,temp1 //把temper1的值送ddrc(c口的方向控制寄存器)即设定为输出模式
out portc,temp1 //PC口全部输出为1,
ldi r16,5 //设置延迟参数
loop:
cbi portc,0
rcall delay
sbi portc,0
rcall delay
rjmp loop
delay: push r16
del1: push r16
del2: dec r16
brne del2
pop r16
dec r16
brne del1
pop r16
ret
问题就是,如果不配置SP指针寄存器,当运行到倒数第二行pop r16的时候,我看到出栈后r16值为:0x20,这个值不知道是怎么出现的,求解!
|