null第四章 汇编语言程序
第四章 汇编语言程序设计三、汇编语言源程序的格式
汇编语言的语句一般自左到右按序至少包括以下四项:
标号:操作码 操作数;注释
注意:
1.标号的第一个字符必须是英文字母,随后的可以是英文字母或数字。
2.在操作码和操作数之间应该有空格。4 . 1 程序设计概述一、程序设计步骤二、程序设计
4 . 2 汇编语言基本程序设计4 . 2 汇编语言基本程序设计例:将片外0200H、0201H单元两个无符号数相乘,结果送片内RAM的50H、51H单元。4.2.1 顺序结构程序 ORG 0000H
M1 EQU 0200H;乘数首地址
M2 EQU 50H;乘积首地址
AJMP MAIN
ORG 0100H
MAIN: MOV DPTR,#M1;指向被乘数
MOV A,#64H
MOVX @DPTR,A ;将100送0200H
INC DPTR
MOV A,#0AH
MOVX @DPTR,A;将10送0201HMOV DPTR,#M1;指向数据区
MOV R0,#M2;R0指向结果单元
MOVX A,@DPTR;取被乘数
MOV B,A
INC DPTR
MOVX A,@DPTR;取乘数
MUL AB
MOV @R0,A;存积低字节到50H
MOV A,B
INC R0
MOV @R0,A;存积高字节到51H
AJMP $null MOV A,R3
RL A
MOV DPTR,#TAB
JMP @A+DPTR
TAB:AJMP addr00
AJMP addr01
… …
AJMP addr7F4.2.2 分支程序例:设计可多达128路分支出口的转移程序。设128个出口分别转向128段小程序,它们的入口地址依次为:addr00,addr01, addr02, … ,addr7F;要转移到某分支的信息存放在工作寄存器R3中。null例:设计有256路分支出口的转移程序
MOV DPTR,#TAB
MOV A,R2;取出口信息
CLR C
RLC A;出口信息乘以2
JNC LOW;出口信息在0~127间则转移
INC DPH;出口信息在128~255间,则DPTR加256,使页数加1
LOW: MOV R3,A;暂存出口信息
MOVC A,@A+DPTR;查找出口地址低8位
PUSH A
MOV A,R3
INC A
MOVC A,@A+DPTR;查找出口地址高8位
PUSH A
RET;将出口地址高8位送PC高8位,将出口地址低8位送PC低8位
TAB: DW addr 00
DW addr 01
DW addr 02
… …
DW addr FF
null例:求无符号数累加和 。若Ai均为单字节数,并按i(i=1~n)顺序存放在片内RAM从60H开始的单元中,n放在R2中,
它们的和(双字节)放在R3和R4中。4.2.3 循环程序 ORG 0000H
AJMP ADD1
……..
ORG 0100H
ADD1:MOV R3,#00H;部分和高字节清零
MOV R4,#00H;部分和低字节清零
MOV R2,#8;数据个数送R2
MOV R0,#60H;数据首址送R0
CLR C
LOOP:MOV A,R4;取部分和低位
ADD A,@R0;与Ai相加
MOV R4,A;存部分和INC R0;地址加1
CLR A
ADDC A,R3;部分和高字节加进位
MOV R3,A;存部分和
DJNZ R2,LOOP
END
null例:已知数据0~9的平方,设变量x的值在累加器A中,查表后求 的值放回累加器,试编制程序。4.2.4 查表程序 ORG 0100H
SQR :MOV DPTR,#TABLE
MOVC A,@A+DPTR
RET
TABLE:DB 00H,01H,04H,09H,16H
DB 25H,36H,49H,64H,81H4.2.5 子程序及调用1. 用工作寄存器和累加器传递参数 ORG 00H
X1 EQU 30H
X2 EQU 40H
Y EQU 50H
START:MOV A, X1
ACALL SQR;调查表程序null例:将片内RAM中30H单元开始的10个数据取反后送到片内RAM中40H开始的单元中。2. 用指针寄存器传递参数 ORG 0100H
MOV R2,#0AH;数据块长度送R2
MOV R0,#30H;要处理的数据块首址送R0
MOV R1,#40H;处理后数据块首址送R1
ACALL TRAN;调用求反子程序
ORG 0200H
TRAN:PUSH A
KK :MOV A,@R0;从片内RAM取数据到累加器A
CPL A ;数据求反
MOV @R1,A;存数据到R1指向的片内RAM单元
INC R0
INC R1
DJNZ R2,KK;未处理完,继续转到KK
MOV A,R1 ;当前存放处理结果单元地址送A
CLR C
SUBB A,#0AH;退回到结果数据区首址
XCH A,R1 ;交换
POP A
RETnull例:将R1中的低半字节(低4位)一个16进制数转换成ASCII码,再放回R1。3. 用堆栈传递参数 ORG 00H
AJMP START
START:MOV SP,#50H;堆栈指针
MOV A,R1 ;待处理的16进制数送A
PUSH ACC ;待转换数入栈
LCALL H_ASC;调数制转换子程序
POP ACC ;从堆栈取得转换值
MOV R1,A ;转换值送R1
ORG 0E0H
H_ASC:MOV R1,SP ;R1指向栈顶
DEC R1 ; R1退回到入口参数地址
DEC R1 ;
XCH A,@R1;交换,取出参数送A
ANL A,#0FH ;保留低半字节
null MOV DPTR,#TAB;取ASCII码表首址
MOVC A,@A+DPTR;查表
XCH A,@R1 ;转化好的数据送堆栈
RET
TAB DB 30H,31H,32H,33H,
DB 34H,35H,36H,
DB 37H,38H,39H
DB 41H,42H,43H,44H
DB 45H,46H
null1、多字节二进制数加法例:两个双精度数(8字节数二进制数)相加。 BUF1 EQU 50H;定义被加数首址
BUF2 EQU 60H;加数首址
N EQU 08H;加数字节数
MOV R0,#BUF1;R0指向被加数
MOV R1,#BUF2;R1指向加数
MOV R2,#N ;加数总字节数送R2
ADDBIN:CLR C ;清进位
LOOP :MOV A,@R0 ;取被加数
ADDC A,@R1 ;两数相加,带进位
MOV @R0,A ;和放回被加数单元
INC R0 ;指向被加数的下一个字节
INC R1 ;指向加数的下一个字节
DJNZ R2,LOOP;未加完转LOOP
JC DON ;最高字节相加有进位转
MOV @R0,#00H;无进位R0置零
JMP STOP ;退出,暂停
DON:MOV @R0,#01H ;最高字节求和的进位存R0
STOP:4 . 3 算术逻辑处理程序null2、多字节压缩BCD码加法例:多字节压缩BCD码加法 MOV R0,#ADR1;被加数低字节地址指针
MOV R1,#ADR2;加数低字节地址指针
MOV R3,#N ;字节数
ACALL BCDADD
ORG 0108H
BCDADD:MOV A,R0 ;两个多字节BCD码加法子程序
PUSH A ;被加数首址入栈暂存
MOV A,R3
PUSH A ;加数字节数入栈暂存
CLR C
LP0 :MOV A,@R0 ;取被加数
ADDC A,@R1 ;相加
DA A ;十进制加法调整
MOV @R0,A ;存和
INC R0 ;指针加1
INC R1
DJNZ R3,LP0 ;做完加法否
POP A
MOV R3,A ;恢复R3中的
JNC RETURN ;最高字节相加有无进位
MOV @R0,#01H
INC R3 ;最高字节和有进位,扩展一个字节
RETURN :POP A
MOV R0,A ;恢复R0,指向和的首址
RETnull3、多字节数求补 ADR EQU 60H
N EQU 08H
MOV R2,#N ;待处理的字节数送R2
MOV R0,#ADR ;R0指向待处理的数据
ACALL D_NEG;调用多字节数求补子程序
ORG 00A0H
D_NEG:MOV A,R0
PUSH A ;数据区首址入栈保护
MOV A,@R0 ;从片内RAM60H取最低字节
CPL A ;求反
ADD A,#01H ;最低字节取反后加1
MOV @R0,A ;最低字节处理后放回原处
DEC R2 ;待处理字节数减1
DON : INC R0 ;R0指向下一个数
MOV A,@R0 ;下一个字节送A
CPL A
ADDC A,#0 ;考虑低位字节求反加1后可能的进位
MOV @R0,A ;处理完后放回原处
DJNZ R2,DON
POP A ;处理完,从栈顶弹出结果数据区首址
MOV R0,A ;结果单元首址送R0
RET例:多字节数求补4、多字节无符号数求极大值4、多字节无符号数求极大值 DAT EQU 40H
ORG 0AH
MOV R2,#07H ;R2存比较次数
MOV R0,#DAT;R0指向数据区首址
CLR C
MAX:MOV A,@R0 ;第一个数据送R3
MOV R3,A
INC R0 ;指向下一个数据
MOV A,@R0 ;取下一个数据
SUBB A,R3 ;后一数减前一数,A(i+1)-A(i)
JNC LP ;无借位,后一数大,不交换
MOV A,R3 ;交换数据
XCH A,@R0 ;大字符下沉
DEC R0
XCH A,@R0 ;小字符上浮
INC R0
LP:DJNZ R2,MAX
RET设在DAT开始的片内RAM中存放8个无符号字节数,找出最大值,并暂存在A中。5、冒泡程序5、冒泡程序例:设片内RAM 40H开始的单元有无序字符表,假设为8个字节,将其按代码值大小升序排列。 N EQU 08H ;元素个数
TAB EQU 40H ;数据区首址
MOV R2,#N
MOV R0,#TAB
ACALL ARRAY;调用升序排序子程序
ORG 0100H
ARRAY:DEC R2 ;置外循环次数=N-1(冒泡次数)
SETB 00H ;置交换标志位=1
MOV R7,#00H ;第0次冒泡,R7置0
LP0 :JNB 00H,LP3 ;无交换标志,退出
CLR 00H ;清交换标志
MOV A,R0 ;数据首址送A
MOV R1,A ;R0内容暂存于R1
MOV A,R2 ;N-1送R5
MOV R5,A ;置内循环次数初值=N-1
null CLR C
SUBB A,R7 ;内循环次数=N-1-(R7)
MOV R5,A ;更新内循环次数
LP1:MOV A,@R1;第一个数据送R3
MOV R3,A
INC R1 ;指向第二个数据
CLR C
MOV A,@R1;取第二个数送A
SUBB A,R3 ;相邻元素比较,A(i+1)-A(i)
JNC LP2 ;A(i+1)>A(i)转LP2
MOV A,R3 ;A(i+1)