打印
[经验分享]

8051架构汇编

[复制链接]
1084|1
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
Zuocidian|  楼主 | 2025-3-7 17:01 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
;-----------MCS-51架构汇编(不分大小写),,内存地址,寄存器基本都是8位---
;51架构,16位的地址总线,8位数据总线
;DPTR(数据指针寄存器,16位):作用访问数据存储器(RAM)而设立的
;PC(程序指针寄存器,8位),(PC)=当前指令的 下一条指令的首地址
;


;------------------一.数据传送类指令--------------------------------------------------------
;(A)=40H,40为16进制的数字 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



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



;-----------------选择程序 类似if,switch语句--------------

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

;-----------------选择程序 类似if,switch语句--------------

;外部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
————————————————

                            版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。

原文链接:https://blog.csdn.net/m0_57249200/article/details/132183406

使用特权

评论回复
沙发
weifeng90| | 2025-3-7 19:28 | 只看该作者
汇编基本忘完了,现在用汇编的很少了吧。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

32

主题

70

帖子

0

粉丝