[讨论] 51指令?

jakey0225   2007-10-29 08:45 楼主
PUSH R1 51单片机汇编不能用这个指令? xiuhua.asm(233): error A22: EXPRESSION TYPE DOES NOT MATCH INSTRUCTION

回复评论 (11)

回复:51指令?

PUSH 01H
点赞  2007-10-29 08:47

回复:51指令?

mov a, r1 push acc
点赞  2007-10-29 08:49

4楼 xwj 

回复:51指令?

因为51有4组寄存器,R1可能对应到4个地址,编译器没法确定该用哪个 而PUSH xx是绝对寻址,地址固化在程序代码中了,编译器没法没法判断你到底用的那个寄存器组以及你是否切换过寄存器组,无法确定该用哪个地址,所以只能报错! 因此应该如2楼所说那样: PUSH 01H(当前用得是默认的寄存器组0)
点赞  2007-10-29 08:50

回复:51指令?

当然能确定当前的寄存器组的话,直接入栈直接地址是可以的,C51里这两种方法是可选的
点赞  2007-10-29 08:51

6楼 jer 

回复:51指令?

R0是寄存器,要对它做保护, 只能用它地址 00H
点赞  2007-10-29 08:53

回复:51指令?

如果是KEIL的A51 USING 0;(0-3) 必须加这句,告诉编译器 ;程序现在使用BANK0(0-3) ;现在可以用R0的重复表示AR0等 PUSH AR1;=R0->R7 POP AR1;=R0->R7 一般复位后PSW=0,也就是使用BANK0.
点赞  2007-10-29 08:54

回复: 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)
点赞  2007-10-29 08:55

回复:51指令?

using 0 PUSH AR1
点赞  2007-10-29 08:57

回复: 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
点赞  2007-10-29 09:08

回复:51指令?

如果KEIL不选中“使用绝对寄存器访问”选项的话,就是产生 MOV ACC,R0 PUSH ACC 这样的指令,这样的方式适应性更强,可以使用任意寄存器组,而PUSH AR0的方式是做不到的,当然这样效率高些,但当寄存器组被改变时是不行的。。。
点赞  2007-10-29 09:16
有涨了见识
点赞  2011-9-19 21:28
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 京公网安备 11010802033920号
    写回复