汇编程序详解
❶ 汇编程序详解(请大侠帮忙解释一下汇编程序,统计输入字符串中每个字符的个数)
*********************************************************************************
程序将输出从键盘输入的字符,并显示出相同的字符及相同字符的个数。
*********************************************************************************
注x8086的数组起始0还是1,我记不清了,我是按0算的,根据你的情况看嘛......
DATA SEGMENT 数据段开始
BUFFER DB 100 定义BUFFER数据第1个数据DB类型,且值为100
DB ? 定义1空的DB类型。
DB 100 DUP(?) 定义100个DB类型的数据,初始化
CHARS DB 'INPUT:$' 定义字符串"INPUT:"以$为结束标识
DATA ENDS 数据段结束
CODE SEGMENT 代码段
ASSUME CS:CODE,DS:DATA 段代码声明CS
MAIN PROC FAR 定义"MAIN"函数
***************************************************
PUSH DS 将数据段地址堆栈
SUB AX,AX 清零AX,AX=0
PUSH AX 将AX入栈,实际将压入0堆栈中
MOV AX,DATA 把数据段起始地址放入AX中
MOV DS,AX 初始化DS(数据段地址)
********以上是固定的,又叫程序的初始化数据段*******
START: MOV DX,OFFSET CHARS 取CHARS的字符首地址放入DX中
MOV AH,9 将9号DOS中断功能号,放入AH中,用于显示DX所存的字符串
INT 21H 调用21号中断
********以上用于显示"INPUT:"字符串**********
MOV DX,OFFSET BUFFER 取CHARS的字符首地址放入DX中
MOV AH,0AH 将0A号DOS中断功能号,用于从键盘缓冲输入,并保存DX所存的地址中
INT 21H 调用21号中断
********以上用于从键盘缓冲中输入到BUFFER中,输入的东西将放入BUFFER中*************
MOV DL,0AH 把“换行符”放入DL中
MOV AH,2 02号功能,将从DL中输出一个字符
INT 21H 调用21号中断
*******以上用于换行1,输出换行符**********
MOV DL,0DH 把“回车符”放入DL中
MOV AH,2 02号功能,将从DL中输出一个字符
INT 21H 调用21号中断
*******以上用于换行2,输出回车符**********
*******上两用于换行*******
MOV SI,OFFSET BUFFER 把从键盘输入的字符,BUFFER地址给SI
INC SI 指向第二个字符
MOV AL,[SI] 放入AL
INC SI 指向下一个字符
MOV DL,[SI] SI指向的下一个字符给DL
MOV DH,[SI] 同时给DH
MOV DI,SI DI指向BUFFER的第三个字符
MOV CL,AL CL=AL=BUFFER[1]=100
MOV CH,0 CH=0
MOV BL,1 BL=1
MOV BH,0 BH=0
DEC CL CL减1
GO1: INC SI SI指向下一个字符
CMP DL,[SI] 比较BUFFER[i]与BUFFER[i+]是否相等
JNE TO1 不相等转到TO1
INC BL 如果相等BL将加1
TO1: LOOP GO1 循环CX-1,转到GO1
************以上函数遍历BUFFER中所有字符,并将与BUFFER[1]相同的字符的个数放入BL中,**************
CALL OUTPUT 调用OUTPUT,输出我们能看懂的十位数,显示出来
MOV BL,1 BL=1
TO5: INC DI DI+1,批向下一个地址,DI指向BUFFER第四个字符了
DEC AL AL减1,第一次是AL=99
CMP AL,1 和1比较
JE TO3 如果是1转到TO3
CMP DH,[DI] 和DH字符比较,BUFFER[1]是否相等
JE TO5 如果相等就回到TO5
MOV DL,[DI] 如果不相等的话,将DI指向的字符放入DL中,
MOV SI,DI SI=DI放入SI
MOV CL,AL CL=AL
MOV CH,0 CH=0,CX=CL
DEC CL CL=CL-1
GO2: INC SI 指向下一个字符
CMP [SI],DL 和DL字符比较,BUFFER[1]是否相等
JNE TO2 如果相等就回到TO2
INC BL 相同时BL=BL+1
MOV [SI],DH 将相同的字符放入SI中
TO2: LOOP GO2 CL=CL-1
CALL OUTPUT 显示相同的字符个数
MOV BL,1 BL重新计算,初始化为,因为本身就是一个字符,如果有一个相同就应该有2个相同字符了
JMP TO5 跳到TO5
TO3: CMP DH,[DI] 当AL=1,循环结束以后,将跳到这里来
JE TO4 如果DH这时与DI里地址里所放的值相同,那么就结束。
MOV DL,[DI] 否则[DI]放入DL中
MOV BL,1 给BL为1,因为这时,就只有一个字符了,没有与他相同的字符了。
CALL OUTPUT 把字符个数输出.
TO4: RET
MAIN ENDP
;--------------------------
OUTPUT PROC 自定义函数
PUSH AX //
PUSH CX //
PUSHF //保存现场
MOV AH,2 调用DOS功能号02,将DL中的内容输出,即BUFFER[1]输出
INT 21H 调用INT 21中断
MOV DL,20H “空格”的ASCII码
MOV AH,2 调用DOS功能号02,将DL中的“空格”输出
INT 21H
MOV AL,BL AL=BL,相同字符次数
MOV AH,0 AX=AL
MOV CL,10 CL=10
DIV CL AX=AX/CL=AL/10=BL/10,AL中为商,AH中为余数
ADD AH,30H AH=AH+30,将数字转换成对应ASCII
ADD AL,30H AL=AL+30,将商转换成对应的ASCII码
MOV CH,AH CH放入余数的ASCII码
******************以上是将BL转换成十进制数***********
MOV DL,AL DL放入商的ASCII码
MOV AH,2 调用DOS功能号02,将DL中的AL商值输出,,,实际是重复次数的十位数
INT 21H
*****输出十位数****
MOV DL,CH
MOV AH,2
INT 21H
******输出个位数****
MOV DL,0AH
MOV AH,2
INT 21H
*******以上用于换行1,输出换行符**********
MOV DL,0DH
MOV AH,2
INT 21H
*******以上用于回车2,输出回车符**********
POPF //恢复现场
POP CX //
POP AX //恢复现场
RET //返回
OUTPUT ENDP
CODE ENDS
END MAIN
❷ 求 PIC 8位单片机 汇编指令比较全的,详细点的
Pic 8位单片机汇编指令识读
各大类单片机的指令系统是没有通用性的,它是由单片机生产厂家规定的,所以用户必须遵循厂家规定的标准,才能达到应用单片机的目的。
PIC 8位单片机共有三个级别,有相对应的指令集。基本级PIC系列芯片共有指令33条,每条指令是12位字长;中级PIC系列芯片共有指令35条,每条指令是14位字长;高级PIC系列芯片共有指令58条,每条指令是16位字长。其指令向下兼容。
在这里笔者介绍PIC 8位单片机汇编语言指令的组成及指令中符号的功能,以供初学者阅读相关书籍和资料时快速入门。
一、PIC汇编语言指令格式
PIC系列微控制器汇编语言指令与MCS-51系列单片机汇编语言一样,每条汇编语言指令由4个部分组成,其书写格式如下:
标号操作码助记符操作数1,操作数2;注释
指令格式说明如下:指令的4个部分之间由空格作隔离符,空格可以是1格或多格,以保证交叉汇编时,PC机能识别指令。
1 标号与MCS-51系列单片机功能相同,标号代表指令的符号地址。在程序汇编时,已赋以指令存储器地址的具体数值。汇编语言中采用符号地址(即标号)是便于查看、修改,尤其是便于指令转移地址的表示。标号是指令格式中的可选项,只有在被其它语句引用时才需派上标号。在无标号的情况下,指令助记符前面必须保留一个或一个以上的空格再写指令助记符。指令助记符不能占用标号的位置,否则该助记符会被汇编程序作标号误处理。
书写标号时,规定第一字符必须是字母或半角下划线“—”,它后面可以跟英文和数字字符、冒号(:)制符表等,并可任意组合。再有标号不能用操作码助记符和寄存器的代号表示。标号也可以单独占一行。
2 操作码助记符该字段是指令的必选项。该项可以是指令助记符,也可以由伪指令及宏命令组成,其作用是在交叉汇编时,“指令操作码助记符”与“操作码表”进行逐一比较,找出其相应的机器码一一代之。
3 操作数由操作数的数据值或以符号表示的数据或地址值组成。若操作数有两个,则两个操作数之间用逗号(,)分开。当操作数是常数时,常数可以是二进制、八进制、十进制或十六进制数。还可以是被定义过的标号、字符串和ASCⅡ码等。具体表示时,规定在二进制数前冠以字母“B”,例如B10011100;八进制数前冠以字母“O”,例如O257;十进制数前冠以字母“D”,例如D122;十六进制数前冠以“H”,例如H2F。在这里PIC 8位单片机默认进制是十六进制,在十六进制数之前加上Ox,如H2F可以写成Ox2F。
指令的操作数项也是可选项。
PIC系列与MCS-51系列8位单片机一样,存在寻址方法,即操作数的来源或去向问题。因PIC系列微控制器采用了精简指令集(RISC)结构体系,其寻址方式和指令都既少而又简单。其寻址方式根据操作数来源的不同,可分为立即数寻址、直接寻址、寄存器间接寻址和位寻址四种。所以PIC系列单片机指令中的操作数常常出现有关寄存器符号。有关的寻址实例,均可在本文的后面找到。4 注释用来对程序作些说明,便于人们阅读程序。注释开始之前用分号(;)与其它部分相隔。当汇编程序检测到分号时,其后面的字符不再处理。值得注意:在用到子程序时应说明程序的入口条件、出口条件以及该程序应完成的功能和作用。
二、清零指令(共4条)
1 寄存器清零指令
实例:CLRW;寄存器W被清零
说明:该条指令很简单,其中W为PIC单片机的工作寄存器,相当于MCS-51系列单片机中的累加器A,CLR是英语Clear的缩写字母。
2 看门狗定时器清零指令。
实例:CLRWDT;看门狗定时器清零(若已赋值,同时清预分频器)
说明:WDT是英语Watchdog Timer的缩写字母。CLR见上述说明。注意该两条指令无操作数。
3 寄存器f清零指令。指令格式:CLRF f
实例:CLRF TMRO;对TMRO清零
说明:在PIC系列8位单片机中,常用符号F(或f)代表片内的各种寄程器和F的序号地址。F取值按PIC系列不同型号而不同,一般为Ox00~Ox1F/7F/FF。TMRO代表定时器/计数器TMRO,所以CLRF对寄程器清零,采用了直接寻址方式直接给出要访问的寄存器TMRO。
4 位清零指令。指令格式 BCF f,b
实例:BCF REG1,2;把寄存器REG1的D2位清零
说明:BCF是英语Bit Clear F的缩写。指令格式中的F,同上说明;符号b是表示PIC片内某个8位数据寄存器F的位号(或位地址),所以b的取值为0~7或D0~D7。实例中REG是Register的缩写。实例中的2代表指令格式中的b=2即寄存器REG1的D2位。
通过上述四条清零指令格式和实例,可以说明,学习PIC系列8位单片机的指令时应首先了解指令的助记符意义(功能),再有就是它的表达方式。初学者没有必要死记指令,重要是理解和实践。
本文关于指令的注释将与前述指令中的略有不同。前述指令注释时是对指令具体完成的功能给以说明,这种注释方法对初学者确实易于接受和理解,但是实际应用中的PIC产品汇编语言的注释通常是以程序要做什么(或指令的作用)而不是说指令的直接功能。鉴于上述原因,下述的指令注释将改变过去的注释方法,用程序应起的作用作注释。
10 寄程器半字节交换指令
指令格式:SWAPFf,d
说明:SWAPF是Swap f的合写。符号f、d的意义与前述的相同。该条指令的功能是寄存器f的高4位与低4位交换,即指令执行前,若寄存器f的8位状态为D7、D6、D5、D4、D3、D2、D1、D0,执行后的8位状态变为D3、D2、D1、D0、D7、D6、D5、D4,其结果存入W(d=0)或f(d=1)中。
实例:中断现场保护是中断技术中重要部分。由于PIC16C××指令系统中没有进栈PUSH和出栈POP指令,所以只能用其它指令来实现。因为在主程序中常常用到工作寄存器W和状态寄存器STATUS,所以中断现场保护常要保护寄存器W和STATUS。
下面是对PIC16C7×系列芯片中断现场保护的实例程序。
MOVWF W_TEMP ;将W内容存入到临时寄存器 W_TEMP中SWAPF STATUS,W ;交换STATUS与W内容
MOVWF STATUS_TEMP ;将STATUS的内容存入到临
… 时寄存器STATUS_TEMP中
中断服务程序
…
SWAPF STATUS_TEMP,W;交换STATUS_TEMP与W 的内容MOVWF STATUS 籗TATUS复原成原来的状态
SWAPF W_TEMP,F ;交换内容
SWAPF W_TEMP,W;W复原成原来的状态
说明:上述程序中各条指令的注释基本上都是以程序应达到的目的而注释的,对每条指令的功能几乎未涉及。这是初学者应特别注意的。
11 子程序调用指令(Subroutine Call)
指令格式:CALL k;k为立即地址
说明:子程序调用,不同型号芯片的实现方法不尽相同,其共同点是首先将返回地址((PC)+1)压栈保护,再转入所调用的子程序入口地址执行(与MCS-51指令功能相似)。
指令格式模式:HERE CALL DELAY;调用延时子程序
…
DELAY MOVLW 0x80;延时子程序
RETLW 0
说明:调用指令执行前,PC=地址HERE
调用指令执行后,PC=地址DELAY(标号),堆栈指针TOS=HERE+1(返回地址)。
实例:见下条指令的实例
12 寄存器内容取反指令
指令格式:COMFf,d
说明:COMF是Complement f的缩写。其中d=1时,操作(f)→f;d=0时,操作(f)→w。
功能:寄存器f内容取反后送入W(d=0)或f自身(d=1)。
实例: ORG 0x1FF
GOTO MAIN
ORG 0
DELAY …
MAIN MOVLW 0 ;主程序开始
TRTS 5 ;设置RA口为输出
BCF 5,0 ;置RA口0位为0
LOOP CALL DELAY;闪动延时
COMF 5 ;RA口求反(亮—灭—亮……控制)
GOTO LOOP ;循环
…
说明:上述指令是一种PIC16C54 LED发光控制实验部分程序。其中延时子程序DELY未列出,但不影响本条指令的识读。程序中的主程序开始的三条指令,均已介绍过,紧跟着的CALL指令是调用执行子程序,其入口地址为标号DELAY。子程序执行结束后,又执行COMF 5的LED发光亮—灭…亮—灭……控制指令。后面一条GOTO LOOP指令是达到LED循环点亮目的。
13 面向位的操作指令(共4条,PIC高级产品多增一条)
该类指令除一条位清零外,另有一条寄存器f位b的置1指令和另外两条位跳步指令(PIC高级产品多增一条f的b位触发转换指令)。
(1)位置1指令。指令格式 BSFf,b说明:BSF是Bit Set f的缩写。F和b的意义与前述相同,该条指令的功能是将寄存器f的b位置1。
(2)位测试、为零间跳指令。指令格式 BTFSC f,b说明:BTFSC是Bit Test,Skip if Clear的缩写。指令功能是测试寄存器f位“b”,如为0,跳过下一条指令;为1顺序执行,即当f(b)=0时,就不执行当前指令而执行下一条指令(间跳),即用一条空指令NOP代替它,所以该条指令占用2个指令周期。
(3)位测试、为1间跳指令。指令格式 BTFSSf,b说明:BTFSS是Bit Test,Skip if Set的缩写。其指令的逻辑功能与上条相反,位测试f(b)=1就间跳执行,f(b)=0顺序执行。
上面介绍的PIC 8位单片机汇编语言指令仅是部分指令,此外还有循环左、右移指令;W和寄存器f相“加”、相“与”指令和进入睡眠方式等指令。鉴于报纸版面的限制,不在这里一一介绍,今后将在程序的应用试验中再作补充说明。
有点多,建议你还是打印下来慢慢看!