8051架构汇编

;-----------MCS-51架构汇编(不分大小写),,内存地址,寄存器基本都是8---
;51架构,16位的地址总线,8位数据总线
;DPTR(数据指针寄存器,16):作用访问数据存储器(RAM)而设立的
;PC(程序指针寄存器,8)(PC)=当前指令的 下一条指令的首地址
;


;------------------.数据传送类指令--------------------------------------------------------
;(A)=40H,4016进制的数字 H是16进制数的标志
;--寄存器寻址方式
mov A,Rn;n=0~7,把寄存器Rn中的 (Rn)->A,Rn里的内容不变

;直接寻址
;假设(40H)=56H
mov A,40H;(A)=(40H),RAM(40H)地址内的值 赋值到A寄存器中 则(A)=56H

mov 35H,28H;(28H)->(35H),(RAM)内存地址 28H里的数据 赋值给35H,35H内的原数据没有了存的新的数据
;上边这个寻址方式 是片内所有功能寄存器(SFR)的唯一寻址方式


;寄存器间接寻址
;假设 (R0)=50H,(50H)=99H 
;假设 (R1)=68H,(68H)=11H
mov A,@R0;(A)=(R0)=((50H))=99H, 将寄存器存的地址内的数据赋值给给A寄存器
mov A,@R1;(A)=(R1)=((68H))=11H


;立即数寻址
MOV A,#36H;(A)=36H,直接把16进制数 36赋值给A寄存器
MOV DPTR,#6BF5H;把两个字节的值(16位) 直接赋值给 DPTR寄存器
;DPTR0 / DPTR1 是由辅助寄存器AUXR1.0(DPS) 决定,DPS=0则选用DPTR0 DPS=1 则选用DPTR1


;基地址加变址寻址方式
;这钟寻址方式 只能以 DPTR和PC为基址寄存器
;假设 (A)=50H,(DPTR)=4540H,
MOVC A,@A+DPTR;(A)=((DPTR+A))=(4590H)
MOVC A,A+PC;(A)=((PC+A))


;位寻址方式
MOV C,40H;把位地址 40H的值(0/1)赋值给标志位C
;------------------.数据传送类指令--------------------------------------------------------


;---------------------堆栈操作 (后进先出)-------------------

;入栈 PUSH SP(堆栈指针)+1,然后再把寄存器中的值 赋值到增加后的地址内
;假设 (SP)=60H ,(A)=30H ,(B)=70H
PUSH ACC;(SP)=(SP)+1=60H+1H =61H ,(61H)=(A)=30H, 
PUSH B;(SP)=(SP)+1=62H, (62H)=(B),

;出栈指令 POP 先将数据送出去  SP(堆栈指针)-1
;假设(SP)=62H, (62H)=70H,(61H)=30H
POP DPH; (DPH)=(62H)=70H (SP)=(SP)-1=61H
POP DPL; (DPL)=((SP))=(61H)=30H,(SP)=(SP)-1=60H
;---------------------堆栈操作 (后进先出)-------------------

;累加器A 与外部数据存储器RAM/IO传送指令
MOVX A,@DPTR;(A)=((DPTR)),读外部RAM/IO
MOVX A,@RI;(A)=((RI)),读外部RAM/IO
MOVX @DPTR,A;((DPTR))=(A),写外部RAM/IO
MOVX @RI,A;((RI))=(A),写外部RAM/IO
;MOV加X 表示AT89S52单片机访问的是片外RAM存储器或IO端口寄存器
;在执行前面两条指令的时候 控制信号RD,WR同时有效


;查表指令 MOVC  C表示程序存储器中的代码
;假设(A)=30H,执行的地址1000H处 (PC)=1000H+1H=1001H
MOVC A,@A+PC;(A)=(PC)+(A)=1001H+30H=1031H 同时单片机的程序存储器读选通引脚PSEN非有效

;假设 (DPTR)=8100H,(A)=40H
MOVC A,@A+DPTR;(A)=(DPTR)+(A)

;字节交换指令  只能以A作为源操作数 
;假设 (A)=50H, (40H)=99H
XCH A,40H; (A)=99H,(40h)=50H

;半字节
XCHD A,@Ri;A中的低4位 与RAM内部的低4位进行交换 



;加法指令
ADD A,50H;(A)=(A)+(50H)
ADD A,#50H;(A)=(A)+50
;累加器A中
;如果位7有进位 Cy=1,否则Cy=0
;如果位3有进位 Ac=1,否则Ac=0
;如果位6或位7其中之一有进位,则 OV=1 否则OV=0

;带进位加法指令
ADDC A,20H;(A)=(A)+(20H)+Cy
;(A)=85H,(20H)=FFH,Cy=1
;
;           1 0 0 0  0 1 0 1
;           1 1 1 1  1 1 1 1
;        +)                1
;       -----------------------
;           1 0 0 0 0 1 0 1


;1指令
;寄存器内的值 +1 再存入寄存器内
INC A;(A)=(A)+1

;带进位的减法 指令
;(A)=C9H, (R2)=54H ,Cy=1
SUBB A,R2;(A)=(A)-(R2)-Cy

;1指令
; (A)=0FH 
DEC A;(A)=(A)-1 (A)=0EH


;乘法指令
MUL AB; BA=A*B,高八位存在 B内 低八位存在A内


;除法指令
DIV AB;(A)=A/B, 商存入A中 余数存在B内

;累加器A清0
CLR A;(A)=0 不影响标志位

;累加器A字节求反
CPL A;将累加器A中的内容 全都按位取反


RL A;将A中的位 向左移1位 A.7->A.0

RLC A;带位左环移 A.7->Cy  Cy->A.0

RR A;将A中的内容向右移 A.0->A.7

RRC A;带进位的右环移 A.0->Cy Cy->A.7

SWAP A;累加器半字节交换,将A的高四位 和第四位互换

;逻辑与
ANL A,R0;寄存器A中的值  与R0中的值 按位相与 结果存入A中
ANL A,#40H;(A)^40H


;逻辑或
ORL P1,A;将A中的值 与P1中的值 按位或结果存入 P1

;按位异或
XRL A,R3; A寄存器中的值 与R3寄存器中的值 按位异或(不同为1) 异或后的结果存入A中

START:      MOV 41H,#0  ;41H内的值清零 (41H)=0
            MOV R0,#20H ;(R0)=20H
            MOV R2,#20H ;(R2)=20H
    LOOP:   MOV A,@R0   ;把R0内20H的值赋值给A  (A)=((R0))=(20H)
            JNZ NEXT    ;如果A寄存器内的值不是0  则跳转到NEXT
            INC 41H     ;(41H)=(41H)+1  
    NEXT:   INC R0      ; (R0)=(R0)+1
            DJNZ R2,LOOP;(R2)-1 不为0就跳转 循环21次
            RET ;从堆栈中弹出PC的16位,并把堆栈(SP)-2,然后从PC处开始执行程序


;------------------查表程序设计-实际应用案例---------------------------------

        ;PC 程序指针 存储的是程序存储器中的地址 而ROM只能读取数据 不能写入数据 
        ;PC 也也是只能读取里边的值 不能写入数据
        ADD A,#01H; (A)=01H+00H 把加后的数值赋值给A
        MOVC A,@A+PC;(A)=((A+PC)) 把运算后 A+PC 内存储的地址 地址内的数值赋值给A
        RET      ;输入A的值 返回A的平方
                ;输入(A)=00H  A中存入00H  A输入01H 输出01H, 输入02H 输出04H
        DB 00H,01H,04H,09H,10H,19H,24H,31H,40H,51H



;--------------查表程序设计-----实际应用案例---------------------------------



;-----------------选择程序 类似ifswitch语句--------------

CMPT:   JNB Acc,7,RETURN   ;Acc.7=0  就跳转到RETURN中去
        MOV C,Acc.7        ;为Acc.7的值 赋值给位C
        CPL A              ;把A里的值 都取反            
        ADD A,#1        ;把A的值 +1 放入A中
        MOV Acc.7,C     ;把位C的值 赋值给ACC.7
RETURN: RET 

SINGFUC:        MOV A,40H       ;把内存地址40H的值赋值给 A
                CJNE A,#00H,NZEAR  ;比较A的值和00H是否相等 不相等则跳转到NZEAR
                AJMP NEGT       ;直接跳转到 NEGT语句段
NZEAR:          JB ACC.7,POSI   ;如果ACC.7位等于1 则跳转到POSI
                MOV A,#01H      ;01H的值赋值给A
                AJMP NEGT       ;跳转到 NEGT语句
POSI:           MOV A,#81H      

NEGT:           MOV 41H,A       ;把A的值赋值给41H
                END

D50 ms: MOV R7,#200
       
D1:     MOV R6,#125

D2:     DJNZ R6,D2      ;R6减1 不为零 则跳转到D2 在次循环125次 
        DJNZ R7,D1      ;R7减1 不为零 则跳转到D1
        RET

;-----------------选择程序 类似ifswitch语句--------------

;外部RAM 3000H,3001H单元内容 分别为55H,0DDH 

MOV DPTR,#3000H ;执行后的结果 (DPTR)=3000H
MOV R1,#40H     ;执行后的结果 (R1)=40H
MOVX A,@DPTR    ;(A)=((DPTR))=(3000H)=55H
MOV @R1,A       ;(40H)=55H

INC R1          ;(R1)=40H+1H=41H
INC DPTR        ;(DPTR)=3000H+1H=3001H
MOVX A,@DPTR    ;(A)=(3001H)=0DDH
MOV @R1,A       ;(41H)=0DDH


;  (A)=02H  (SP)=42H   (41H)=FFH  (42H)=FFH   

POP DPH; (DPH)=((SP))=((42H))=FFH ,(SP)=(SP)-1=42H-1H=41H
POP DPL; (DPL)=((SP))=((41H))=FFH (SP)=(SP)-1=41H-1H=40H
;(DPTR)=0FFFFH
MOV DPTR,#3000H; (DPTR)=3000H
RL A;(A)=04H
MOV B,A;(B)=(A)=04H
MOVC A,@A+DPTR;(A)=(04H+3000H)=(3004H)=
PUSH ACC;(SP)=(SP)+1=40H+1=41H (41H)=(ACC)=04H
MOV A,B;(A)=(B)=04H
INC A;(A)=(A)+1=04H+01H=05H
MOVC A,@A+DPTR;(A)=((3005H))=
PUSH ACC;(SP)=(SP)+1=41H+1H=42H, (42H)=(A)=05H
RET
ORG 3000H;
DB 10H,80H,30H,80H,50H,80H;
;(3000H)=10H  (3001H)=80H (3002H)=30H (3003H)=80H (3004H)=50H (3005H)=80H


START:  MOV 41H,#0      ;(41H)=0
        MOV R0,#20H     ;(R0)=20H
        MOV R2,#20H     ;(R2)=20H
LOOP:   MOV A,@R0       ;(A)=((R0))=(20H)=?
        JNZ NEXT        ;如果累加器A中的内容不等于0就跳转,类似于 if( (A)!=0 ){   }
        INC 41H         ;自加1 类似于i++ (41H)=(41H)+1 地址41H里的内容+1
NEXT:   INC R0          ; (INC)=(INC)+1=20H+1H
        DJNZ R2,LOOP    ; 减一不为零就跳转 if( ( (R2)-1)!=0  ){ }
        RET             ;




;-----------定时器中断配置----------
        ORG 0000H   ;指令开始的地址
RESET:  LJMP MAIN   ;长跳转指令 跳转到MAIN中去 本质就是把MAIN的程序地址赋值给PC指针了
        
        ORG 000BH   ;指令开始的地址
        LJMP ITOP   ;长跳转指令 跳转到ITOP
        ORG 1000H   ;指令开始的地址



;--------------主程序------------------
MIAN:   MOV SP,#60H     ;(sp)=60H
        MOV B,#0AH      ;(B)=0AH 10
        MOV TMOD,01H    ;设置工作方式
        MOV TL0,0B0H    ;给T0 L寄存器赋值
        MOV TH0,#3CH    ;给T0 H寄存器赋值
        SETB ET0        ;打开定时器T0的开关
        SETB EA         ;打开总开关
        SETB TR0        ;定时器开始运行 
HERE:   SJMP HERE       ;死循环



;-------------中断子程序--------------
ITOP:   MOV TL0,#0B0H
        MOV TH0,#3CH
        DJNZ B,RTURN ; (B)=(B)-1 不为零 就跳转
        CLR TR0  ;
        SETB F0  ;
RTURN:RETI 





;;题目要求:P10上升沿时对P11输入的脉冲进行计数 P12下降沿时 停止计数 计数值存入R0 R1 高位R1 低位R0
; P11 输入脉冲接INT0 用T0计数器完成计数

ORG     0000H
LJMP    MAIN
ORG     000BH
LJMP    ITOP
MAIN:   JNB P1.0,MAIN ;P1.0等于0就跳转
        MOV TMOD,



代码文件

链接:https://pan.baidu.com/s/1AqfWHGM7eqITcdex61xFvQ?pwd=nzlh
提取码:nzlh

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值