PUSH R1
51单片机汇编不能用这个指令?
xiuhua.asm(233): error A22: EXPRESSION TYPE DOES NOT MATCH INSTRUCTION
回复:51指令?
mov a, r1
push acc
回复:51指令?
因为51有4组寄存器,R1可能对应到4个地址,编译器没法确定该用哪个
而PUSH xx是绝对寻址,地址固化在程序代码中了,编译器没法没法判断你到底用的那个寄存器组以及你是否切换过寄存器组,无法确定该用哪个地址,所以只能报错!
因此应该如2楼所说那样: PUSH 01H(当前用得是默认的寄存器组0)
回复:51指令?
当然能确定当前的寄存器组的话,直接入栈直接地址是可以的,C51里这两种方法是可选的
回复:51指令?
R0是寄存器,要对它做保护, 只能用它地址 00H
回复:51指令?
如果是KEIL的A51 USING 0;(0-3) 必须加这句,告诉编译器
;程序现在使用BANK0(0-3)
;现在可以用R0的重复表示AR0等
PUSH AR1;=R0->R7
POP AR1;=R0->R7
一般复位后PSW=0,也就是使用BANK0.
回复: 51指令?
看看编译器如何做
下面是一段C程序:
#include <stdio.h>
int interruptcnt;
int second;
void timer0 (void) interrupt 1 // 注意没有使用 "using 2"
{
if (++interruptcnt == 4000)
{ /* count to 4000 */
second++; /* second counter */
interruptcnt = 0; /* clear int counter */
}
}
void main(void)
{
interruptcnt=0;
second=0;
printf("I do it in this way !");
}
编译器产生的T0中断的LST文件如下:
; FUNCTION timer0 (BEGIN)
0000 C0E0 PUSH ACC
0002 C0D0 PUSH PSW;!!!!!!!!!!!!!!!!!!!!!!!!
0004 75D000 MOV PSW,#00H;!!!!!!!!!!!!!!!!!!!
0007 C006 PUSH AR6;!!!!!!!!!!!!!!!!!!!!!!!!
0009 C007 PUSH AR7;!!!!!!!!!!!!!!!!!!!!!!!!
; SOURCE LINE # 9
; SOURCE LINE # 11
000B 0500 R INC interruptcnt+01H
000D E500 R MOV A,interruptcnt+01H
000F 7002 JNZ ?C0004
0011 0500 R INC interruptcnt
0013 ?C0004:
0013 FF MOV R7,A
0014 AE00 R MOV R6,interruptcnt
0016 BE0F11 CJNE R6,#0FH,?C0002
0019 BFA00E CJNE R7,#0A0H,?C0002
; SOURCE LINE # 12
; SOURCE LINE # 13
001C 0500 R INC second+01H
001E E500 R MOV A,second+01H
0020 7002 JNZ ?C0005
0022 0500 R INC second
0024 ?C0005:
; SOURCE LINE # 14
0024 750000 R MOV interruptcnt,#00H
0027 750000 R MOV interruptcnt+01H,#00H
; SOURCE LINE # 15
; SOURCE LINE # 16
002A ?C0002:
002A D007 POP AR7;!!!!!!!!!!!!!!!!!!!!!!!!!!!!
002C D006 POP AR6;!!!!!!!!!!!!!!!!!!!!!!!!!!!!
002E D0D0 POP PSW;!!!!!!!!!!!!!!!!!!!!!!!!!!!!
0030 D0E0 POP ACC
0032 32 RETI
; FUNCTION timer0 (END)
回复:51指令?
using 0
PUSH AR1
回复: 51指令?
如果要把R1~R7入栈,将成为:
MOV A,R1
PUSH ACC
MOV A,R2
PUSH ACC
MOV A,R3
PUSH ACC
......
出栈时:
POP ACC
MOV R7,A
POP ACC
MOV R6,A
......
谁也看不懂,连自己都要小心弄错。
再看2楼:假设要把01区的R1~R7入栈:
PUSH 9
PUSH 0AH
PUSH 0BH
......
出栈时:
POP ?
.......
POP 0BH
POP 0AH
POP 9
再看按照规范:
using 1 ;或者using 0/using 2/using 3
PUSH AR1
PUSH AR2
PUSH AR3
......
出栈时
POP AR7
POP AR6
POP AR5
......
POP AR2
POP AR1
回复:51指令?
如果KEIL不选中“使用绝对寄存器访问”选项的话,就是产生
MOV ACC,R0
PUSH ACC
这样的指令,这样的方式适应性更强,可以使用任意寄存器组,而PUSH AR0的方式是做不到的,当然这样效率高些,但当寄存器组被改变时是不行的。。。