精华内容
下载资源
问答
  • 25.如果“JA P”指令的操作码放在0050H, 该指令的位移量为34H,执行完此条指 令转移到取下一条指令的偏移地址为( ) A.0082H B.0084H C.0086H D.0088H 26.若DS=1000H,BX=2000H,(12000H)=56H,(12001H)...
  • 目录汇编语句格式标识符硬指令、执行性语句伪指令、说明性语句变量定义变量名初值表变量定义伪指令助记符定义字节单元伪指令DB定义字单元伪指令DW定义双字单元伪指令DDPTR操作符顺序程序设计求两数之和移位代码转换 ...

    作为汇编语言的课程笔记,方便之后的复习与查阅

    本篇为课程第十和第十一次课内容

    汇编语句格式

    标识符

    • 标识符(Identifier)一般最多由31个字母、数字及规定的特殊符号(如 _、$、?、@)组成,不能以数字开头。默认情况下,汇编程序不区别标识符中的字母大小写
    • 一个程序中,每个标识符的定义是唯一的,还不能是汇编语言采用的保留字。
    • 保留字(Reserved Word)是汇编程序已经利用的标识符,主要有:
      硬指令助记符——例如:MOV、ADD
      伪指令助记符——例如:DB、EQU
      操作符——例如:OFFSET、PTR
      寄存器名——例如:AX、CS

    硬指令、执行性语句

    硬指令:使CPU产生动作、并在程序执行时才处理的语句

    执行性语句——由硬指令构成的语句,它通常对应一条机器指令,出现在程序的代码段中,格式:

    标号: 硬指令助记符 操作数,操作数				;注释
    again: mov 			dx,		offset string		;注释
    
    • 标号:反映硬指令位置(逻辑地址)的标识符,后跟一个冒号分隔
    • 硬指令助记符:可以是任何一条处理器指令
    • 处理器指令的操作数可以是立即数、寄存器和存储单元

    伪指令、说明性语句

    伪指令(Directive)——不产生CPU动作、在程序执行前由汇编程序处理的说明性语句
    伪指令与具体的处理器类型无关,但与汇编程序的版本有关

    说明性语句——由伪指令构成的语句,它通常指示汇编程序如何汇编源程序:

    名字  伪指令助记符  参数,参数,…		;注释
    string 	db 		‘Hello,world’		;注释
    
    • 名字:反映伪指令位置(逻辑地址)和属性的标识符,后跟空格或制表符分隔,没有冒号
    • 伪指令助记符:定义字节数据和字符串的DB就是伪指令
    • 伪指令的参数可以是常数、变量名、表达式等,可以有多个,参数之间用逗号分隔

    变量定义

    变量定义(Define)伪指令为变量申请固定长度的存储空间,并可同时将相应的存储单元初始化

    变量定义伪指令要放在.exit后,end之前,因为它不是可执行的语句

    变量名

    变量名为用户自定义标识符,表示初值表首元素的逻辑地址;用这个符号表示地址,常称为符号地址。设置变量名是为了方便存取它指示的存储单元。变量名可以没有。这种情况,汇编程序将直接为初值表分配空间。

    初值表

    初值表是用逗号分隔的参数

    主要由数值常数、表达式或?DUP组成

    • ?——表示初值不确定,即未赋初值
    BUFFER	DB ?
    
    • DUP——表示重复初值
      DUP的格式为:重复次数 DUP(重复参数)
    BUFFER	DB 10 dup(0)
    BUFFER	DB 10 dup(?)
    

    变量定义伪指令助记符

    DB——定义字节伪指令
    DW——定义字伪指令
    DD——定义双字伪指令

    DF——定义3字伪指令
    DQ——定义4字伪指令
    DT——定义10字节伪指令

    重点掌握前三个

    定义字节单元伪指令DB

    DB伪指令用于分配一个或多个字节单元,并可以将它们初始化为指定值

    初值表中每个数据一定是字节量(Byte),存放一个8位数据:

    • 0~255的无符号数
    • -128~+127带符号数
    • 字符串常数
    X	db 'a',-5
    	db 2 dup(100),?		;第二行没有带名字,默认由x往下继续进行内存分配
    Y	db 'ABC'
    

    在这里插入图片描述

    定义字单元伪指令DW

    初值表中每个数据一定是字量(Word),一个字单元可用于存放任何16位数据:

    • 一个段地址
    • 一个偏移地址
    • 两个字符
    • 0~65535之间的无符号数
    • -32768~+32767之间的带符号数
    count	dw 8000h,?,'AB'			; A在高地址处
    maxint	equ 64h					; equ是等价的意思,表示之后maxint就是64h
    number	dw maxint
    array	dw maxint dup(0)
    

    在这里插入图片描述

    定义双字单元伪指令DD

    初值表中每个数据是一个32位的双字量(Double Word):

    • 有符号或无符号的32位整数
    • 用来表达16位段地址(高位字)和16位的偏移地址(低位字)的远指针
    vardd	DD 0,?,12345678h
    farpoint	DD 00400078h
    

    PTR操作符

    PTR操作符使名字或标号具有指定的类型

    • 类型名可以是
      BYTE/WORD/DWORD/FWORD/QWORD/TBYTE
    mov byte ptr [2000H],10H
    

    使用PTR操作符,可以临时改变名字或标号的类型

    顺序程序设计

    求两数之和

    NUM1和NUM2单元中各存放着一个双字无符号数,编制程序计算两数之和,将结果存于SUM双字单元中,进位保存到FSUM字节单元中

    • 分析:最多一次处理16位,双字需分开处理
    .model tiny
    .code
    .startup 
    	mov ax,word ptr num1    	;处理低16位
    	add ax,word ptr num2
    	mov word ptr sum,ax     	;保存低16位
    	mov ax,word ptr num1+2  	;处理高16位
    	adc ax,word ptr num2+2
    	mov word ptr sum+2,ax   	;保存高16位
    	
    	mov dx,0 		   			;最高进位
    	rcl dl,1
    	mov fsum,dl		   			;保存进位	
    	.exit 0           
    	                     
    	num1   dd 82348567H
    	num2   dd 87658321H
    	sum   dd ?
    	fsum   db ? 
    end
    

    也可以用串操作

    移位

    ddvarw为一个32位的数据12ab56cdH,编程将其整个循环左移4位(使用顺序结构)得到 2ab56cd1H

    在这里插入图片描述

    .model tiny
    .code
    .startup
    	mov ax,word ptr ddvar  		;低16位
    	mov dx,word ptr ddvar+2		;高16位
    	mov  cl , 4
    	mov  bh , dh				;保存高8位到BH 
    	mov  bl , ah				;保存低8位到BL
    	shl  dx  , cl 				;高16位左移 4位
    	shl  ax , cl  				;低16位左移 4位
    	shr  bh , cl 				;高8位右移4位,高4位到bh中
    	shr  bl , cl 				;低8位右移 4位,低4位到bl中
    	or   dl , bl  				;原低4位转到高4位
    	or   al, bh   				;原高4位转到低4位
    	.exit 0 
    	
    	ddvar	dd 12ab56cdh
    end
    
    

    代码转换 XLAT

    用查表法,实现一个8位二进制数(00-0FH)转换为ASCII码显示

    .model tiny
    .code
    .startup
    	mov bx,offset ASCII			;BX指向ASCII码表
    	mov al,hex					;AL取得一位16进制数,	
    	and al,0fh					;只有低4位是有效的,高4位清0
    	xlat						; 换码:AL←DS:[BX+AL]
    	mov dl,al					;入口参数:DL←AL
    	mov ah,2					;02号DOS功能调用
    	int 21h						;显示一个ASCII码字符
    	.exit 0
    
    	ASCII db 30h,31h,32h,33h,34h,35h
    	      db 36h,37h,38h,39h	;0~9的ASCII码
    	      db 41h,42h,43h,44h,45h,46h ;A~F的ASCII码
      	hex db 0bh    ;任意设定了一个待转换的1位16进制数
    end
    

    分支程序设计

    • 判断的条件是各种指令,如CMPTEST等执行后形成的状态标志
    • 转移指令JccJMP可以实现分支控制

    二分支

    比较两个数大小:在DATA1和DATA2单元中各有一个16位二进制无符号数,找出其中较小的数,存于MIN单元中

    .model tiny
    .code
    .startup
    	mov ax,data1
    	cmp ax,data2
    	jb next
    	mov ax,data2 		;CF=0
    	next:  
    		mov min,ax		;存结果
    	.exit 0
    
    	data1   dw  2000h
    	data2   dw  3f80h
    	min      dw  ?
    end
    

    三分支

    判断变量var中的值,若为正数,在result中存入1;为负数,在result中存入-1;为零,在result中存入0

    .model tiny
    .code
    .startup
    	mov ax,var
    	cmp ax,0
    	jz zero  				;等于0
    	jg great				;大于0
    	mov ax,0ffffh			;小于0
    	jmp ext
    	
    	zero: mov ax,0
    		 jmp next
    	great: mov ax,0001h
    	next: mov result,ax
    	.exit 0
    	   
    	var	dw 8001h
    	result  	dw 0
    end	
    

    多分支

    (了解即可)

    • 可用跳跃表法,使程序根据不同的条件转移到多个程序分支中去执行

    需要在数据段事先安排一个按顺序排列的转移地址表。因为转移地址为16位偏移地址,所以表地址偏移量需要加2(type=2)调整。可用JMP指令的变址寻址,或寄存器间接寻址,或基址变址寻址方式来实现跳跃表法的程序

    Table dw disp1,disp2,disp3,disp4,disp5,disp6,disp7,disp8
    

    在这里插入图片描述
    :根据键盘输入的1-8数字跳转到8个不同的处理程序段

    .model tiny
    .code
    .startup
    	start1:
    		mov dx,offset msg		;9号功能显示字符串
    		mov ah,9
    		int 21h
    		mov ah,1				;1号功能获取用户输入
    		int 21h
    		cmp al,'1'				;输入不是1~8,则跳转回去
    		jb start1
    		cmp al,'8'
    		ja start1
    		and ax,000fh			;设置地址偏移
    		dec ax
    		shl ax,1				;因为是双字,所以地址偏移需要用shl来乘2
    		mov bx,ax
    		jmp table[bx]
    	start2:
    		mov ah,9
    		int 21h
    		.exit 0
    	disp1:
    		mov dx,offset msg1
    		jmp start2
    	disp2:
    		mov dx,offset msg2
    		jmp start2
    	……
    	disp7:
    		mov dx,offset msg7
    		jmp start2
    	disp8:
    		mov dx,offset msg8
    		jmp start2
    		
    	Msg db 'Input Number(1~8):',0dh,0ah,'$'
    	Msg1 db 'Chapter 1!',0dh,0ah,'$'
    	Msg2 db 'Chapter 2!',0dh,0ah,'$'
    	Msg3 db 'Chapter 3!',0dh,0ah,'$'
    	Msg4 db 'Chapter 4!',0dh,0ah,'$'
    	Msg5 db 'Chapter 5!',0dh,0ah,'$'
    	Msg6 db 'Chapter6!',0dh,0ah,'$'
    	Msg7 db 'Chapter 7!',0dh,0ah,'$'
    	Msg8 db 'Chapter 8!',0dh,0ah,'$'
    	Table dw disp1,disp2,disp3,disp4,
    	      dw disp5,disp6,disp7,disp8
    end
    

    循环程序设计

    • 循环指令和转移指令可以实现循环控制

    例1: 求1+2+3+…+100的和,存在sum字单元

    .model tiny
    .code
    .startup
    	xor ax,ax    		;被加数AX清0
    	mov cx,100
    	again:
    		add ax,cx	    ;从100,99,...,2,1倒序累加
    		loop again
    	mov sum,ax   	;将累加和送入指定单元
    	.exit 0
        sum	dw ?
    end
    

    例2:把BX中的数以十六进制的形式显示在屏幕上。比如BX=8F6AH,屏幕显示 8F6AH
    这个例子要重点理解

    • 要把bx中数据转成ascii码
    • 用循环移位,先显示高4位的16进制数,接着继续移位处理其他位

    在这里插入图片描述

    	mov    	ch, 4			;循环4次
    rotate:       
    	mov    	cl, 4			;每次移位4位
    	rol   	bx, cl
    	mov    	al, bl			;只取bx低4位
    	and     al, 0fh
    	add   	al, 30h			;’0’-’9’ ASCII 30H-39H
    	cmp    	al, 3ah
    	jl      printit		;有符号数的比较
    	add     al, 7h			;’A’-’F’ ASCII 41H-46H
    printit:      
    	mov    	dl, al
    	mov    	ah, 2
    	int    	21h
    	dec    	ch
    	jnz    	rotate
    

    例3:在数据段中从buffer单元开始存放10个16位二进制有符号数,把其中最大数找出来存于MAX单元中

    .model tiny
    .code
    .startup
    	mov bx,offset buffer
    	mov cx,10
    	mov ax,[bx] 
    	circle:
    	 	inc bx			;16位,地址一次要加2
    		inc bx 
    		cmp ax,[bx]
    		jge next
    		mov ax,[bx]
    	next:	
    		loop circle
    		mov max,ax
    	.exit 0
    
    	buffer dw  -100,3000,-1,22,8000h
    		   dw  9232,0,-3632,-3144,6322
    	max    dw  ?
    end
    

    例4:字符串比较——比较内存中的两个字符串string1string2,字符串长度都为COUNT个。若完全相同,则将RESULT单元清0;不同则将RESULT单元送ffh

    .model tiny
    .code
    .startup
    	mov si,	offset string1
    	mov di,	offset string2
    	mov cx,	count
    	cld
    	repz cmpsb  						;重复比较两个字符
    	jnz unmat 							;zf=0,字符串不等,转移
    	mov al,0	  						;zf=1,字符串相等,设置00h
    	jmp output  						;转向output
    	unmat:	mov al,0ffh 				;设置ffh
    	output:	mov result,al 				;输出结果标记
    	.exit 0
    	
    	string1 	db  ‘Hello,Everybody!’
    	string2 	db  ‘Hello,everybody!’
    	count 		equ $-string2  			;$代表count的地址,因此count就为string2字符串的个数
    end
    

    有不同字符时,SI,DI中分别存放第一个不相同字符的下一个地址;CX中存放剩下还未比较的字符个数

    例5:字符串搜索——从一个字符串中查找一个指定的字符T。若找到,则将该字符存入char单元,并记录该字符所在位置的偏移地址,存于caddr中;若未找到,则将char置为0ffh(全1)。

    .model tiny
    .code
    .startup
    	lea  di, mess				;lea 获取一个变量的有效地址 等价于mov di, offset mess
    	mov  al, ‘T’
    	mov  cx, count
    	cld
    	repne  scasb
    	jnz over    				;zf=0,未找到
    	;zf=1,找到
    	mov char, al				;存字符值
    	dec di 
    	mov caddr,di 				;存字符地址
    	over:	.exit
    	
    	mess  db  	‘COMPUTER’
    	count equ 	$-mess
    	char  db 	0ffh
    	caddr dw 	?
    end
    

    例6:将首地址为array的字节数组从小到大排序——冒泡法

    	mov cx,count		;CX←数组元素个数
    	dec cx				;元素个数减1为外循环次数
    outlp:	mov dx, cx		;DX←内循环次数
    	mov bx, offset array
    inlp:	mov al,[bx]		;取前一个元素
    	cmp al,[bx+1]		;与后一个元素比较
    	jna next			;前一个不大于后一个元素,则不进行交换
    	xchg al,[bx+1]		;否则,进行交换
    	mov [bx],al
    next:	inc bx			;下一对元素
    	dec dx
    	jnz inlp			;内循环尾
    	loop outlp			;外循环尾
    

    子程序设计

    子程序的常见格式

    subname	proc	;具有缺省属性的subname过程
    	push ax		;保护寄存器:顺序压入堆栈
    	push bx		;ax/bx/cx仅是示例
    	push cx
    	…			;过程体
    	pop cx		;恢复寄存器:逆序弹出堆栈
    	pop bx
    	pop ax
    	ret			;过程返回
    subname	endp	;过程结束
    

    子程序的参数传送

    • 入口参数(输入参数):主程序提供给子程序
    • 出口参数(输出参数):子程序返回给主程序
    • 参数的形式:
      ① 数据本身(传值
      ② 数据的地址(传址
    • 传递的方法:
      寄存器变量堆栈

    无参数传递的子程序

    ;子程序功能:实现光标回车换行
    dpcrlf	proc	;过程开始
    	push ax		;保护寄存器AX和DX
    	push dx
    	mov dl,0dh	;显示回车
    	mov ah,2
    	int 21h
    	mov dl,0ah	;显示换行
    	mov ah,2
    	int 21h
    	pop dx		;恢复寄存器DX和AX
    	pop ax
    	ret			;子程序返回
    dpcrlf	endp	;过程结束
    

    通过寄存器传递参数

    • 把参数存于约定的寄存器中,可以传值,也可以传址。
    • 子程序对带有出口参数的寄存器不能保护和恢复(主程序视具体情况进行保护)
    • 子程序对带有入口参数的寄存器可以保护,也可以不保护(视具体情况而定)

    例1:将AL中存放的低4位二进制数转换为相应的ASCII码子程序。
    入口参数: (AL) 存放二进制数;
    出口参数: (AL)存放ASCII码。

    htoasc    proc
    	and   al,0fh 
    	add   al,30h
    	cmp  al,3ah
    	jl  htoasc;0~9
    	add   al,7;A~F
    htoasc1: ret
    htoasc    endp
    

    例2:计算字符串长度子程序。字符串是以ASCII码值0(NULL)为结束标志的一组ASCII码字符序列
    入口参数:si为字符串起始地址
    出口参数:ax为字符串的长度

    strlen   proc
    	mov di,si
    	mov ax,ds
    	mov es,ax  		;es:di指向字符串
    	xor al,al      	;(al)清零
    	mov cx,0ffffh   ;(cx)置初值 cx赋为ffffh=-1表示一直循环
    	cld
    	repnz scasb   	;查找结束符
    	mov ax,cx		;cx最后为-cnt-1,cnt为循环次数。取反相当于1111 1111 – cx = -1 + cnt + 1 = cnt
    	not ax          ;含结束符长度
    	dec ax          ;去掉结束符
    	ret
    strlen   endp 
    

    通过变量传递参数

    主程序与子程序公用一组变量,实现参数的传递。不同模块间共享时,需要声明。这种结构独立性差

    通过堆栈传递参数

    • 主程序将子程序的入口参数压入堆栈,子程序从堆栈中取出参数
    • 子程序将出口参数压入堆栈,主程序弹出堆栈取得它们

    要注意堆栈的分配情况,保证参数存取正确、子程序正确返回,并保持堆栈平衡

    • 主程序实现平衡堆栈: add sp,n
    • 子程序实现平衡堆栈: ret n

    :求字数组array中所有元素的累加和(设结果无溢出),结果存于sum

    ;主程序
    .model tiny
    .code
    .startup
    	mov ax,offset array 	;数组首地址
    	push ax
    	mov ax , count			;数组长度
    	push ax
    	mov ax,offset sum		;sum地址
    	push ax
    	call sumc				;调用子程序
    	.exit 0
    	
    	array   dw 100 dup(20)
    	count   equ ($-array)/2	 
    	sum     dw ?
    end
    
    ;子程序
    sumc	proc
    	push bp
    	mov bp,sp		;利用BP间接寻址存取参数,SP为堆栈的栈顶指针
    	push ax
    	push cx
    	push si
    	push di
    	mov si,[bp+8] 	;SS:[BP+8]指向array偏移地址
    	mov cx,[bp+6] 	;SS:[BP+6]指向元素个数
    	mov di,[bp+4] 	;SS:[BP+4]指向sum偏移地址
    	xor ax,ax
    sumc1:	add ax,[si] 
    	add si,2
    	loop sumc1
    	mov [di],ax   	;存放结果
    	pop di
    	pop si
    	pop cx
    	pop ax
    	pop bp
    	ret 6 			;表示将堆栈指针加6,之前主程序调用时入栈了3个字,现在加6使堆栈恢复原来的状态
    sumc	endp
    end
    

    在这里插入图片描述

    嵌套子程序

    ;实现AL内容的显示
    ALdisp	proc	
    	push ax
    	push cx		
    	push ax	 		;暂存ax
    	mov cl,4
    	shr al,cl	 	;转换、显示al的高4位
    	call htoasc	 	;转换子程序调用(嵌套)
    	call dischar 	;显示子程序调用(嵌套)
    	pop ax	 		;转换、显示al的低4位
    	call htoasc	 	;转换子程序调用(嵌套)
    	call dischar 	;显示子程序调用(嵌套)
    	pop cx
    	pop ax
    	ret
    ALdisp	endp
    
    ;实现AX内容的显示
    AXdisp	proc	
    	push ax      	;保护ax
    	push ax	 		;暂存ax
    	mov al,ah
    	call ALdisp 	;显示ah,子程序调用(嵌套)
    	pop ax	 		;恢复AX
    	call ALdisp 	;显示al,子程序调用(嵌套)		
    	pop ax       	;恢复AX
    	ret
    AXdisp	endp
    
    
    ;将AL低4位表达的一位16进制数转换为ASCII码
    htoasc	proc
    	and al,0fh
    	cmp al,9
    	jbe htoasc1
    	add al,37h	
    	ret	
    htoasc1:	add al,30h	
    	ret	
    htoasc 	endp
    
    ;将AL中的ASCII码表示的字符在屏幕上显示输出
    dischar  proc
    	push ax
    	push dx
    	mov dl,al	;显示
    	mov ah,2
    	int 21h
    	pop dx
    	pop ax
    	ret			;子程序返回
    dischar  endp
    

    综合例题

    显示有符号十进制数

    • 子程序在屏幕上显示一个有符号十进制数
    • 子程序还包含将二进制数转换为ASCII码的过程
    • 显示时,负数用“-”引导,正数直接输出、没有前导字符
    • 子程序的入口参数用共享变量传递,主程序调用该子程序显示10个数据

    程序处理过程:

    • 首先判断数据是零、正数或负数,是零显示“0”退出
    • 是负数,显示“-”,求数据的绝对值;
    • 接着数据除以10,余数加30H转换为ASCII码压入堆栈
    • 重复上一步,直到余数为0结束
    • 依次从堆栈弹出各位数字,进行显示

    本例采用16位寄存器表达数据,所以只能显示+327677~-32768间的数值

    .code
    .startup
    	mov cx,count
    	mov bx,offset array
    again:	mov ax,[bx]
    	mov wtemp,ax	;将入口参数存入共享变量
    	call write		;调用子程序显示一个数据
    	inc bx
    	inc bx
    	call dpcrlf		;便于显示下一个数据
    	loop again
    	.exit 0 
    	
    	count	= 10
    	array	dw 1234,-1234,0,1,-1,32767
    			dw -32768,5678,-5678,9000
    	wtemp	dw ?	;共享变量
    end
    
    ;显示有符号10进制数的通用子程序
    ;入口参数:共享变量wtemp
    write	proc
    	push ax
    	push bx
    	push dx
    	mov ax,wtemp	;取出显示数据
    	test ax,ax		;判断零、正数或负数
    	jnz write1
    	mov dl,'0'		;是零,显示“0”后退出
    	mov ah,2
    	int 21h
    	jmp write5
    
    write1:	jns write2	;是负数,显示“-”
    	mov bx,ax		;AX数据暂存于BX
    	mov dl,'-'
    	mov ah,2
    	int 21h
    	mov ax,bx
    	neg ax			;数据求补(求绝对值)
    
    write2:	mov bx,10	;10压入堆栈,作为退出标志
    	push bx
    	
    write3:	cmp ax,0	;数据(余数)为零
    	jz write4		;转向显示
    	sub dx,dx		;扩展被除数DX.AX
    	div bx			;数据除以10:DX.AX÷10
    	add dl,30h		;余数(09)转换为ASCII码
    	push dx			;数据各位先低位后高位压入堆栈
    	jmp write3
    	
    write4:	pop dx		;数据各位先高位后低位弹出堆栈
    	cmp dl,10		;是结束标志10,则退出
    	je write5
    	mov ah,2		;进行显示
    	int 21h
    	jmp write4
    	
    write5:	pop dx
    	pop bx
    	pop ax
    	ret			;子程序返回
    	
    write	endp
    end
    

    计算有符号数平均值

    • 子程序将16位有符号二进制数求和,然后除以数据个数得到平均值
    • 子程序的入口参数利用堆栈传递,主程序需要压入数据个数和数据缓冲区的偏移地址。子程序通过BP寄存器从堆栈段相应位置取出参数
    • 子程序的出口参数用寄存器AX传递
    • 主程序提供10个数据,并保存平均值
    .code
    .startup
    	mov ax,count
    	push ax			;压入数据个数
    	mov ax,offset array
    	push ax			;压入缓冲区偏移地址
    	call mean		;调用子程序求平均值
    	add sp,4		;平衡堆栈
    	mov wmed,ax		;保存平均值(不含余数)
    	.exit 0 	
    	
    count	= 10
    array	dw 1234,-1234,0,1,-1,32767
    		dw -32768,5678,-5678,9000
    wmed	dw ? 		;存放平均值
    
    ;计算16位有符号数平均值子程序
    ;入口参数:顺序压入数据个数和缓冲区偏移地址
    ;出口参数:AX=平均值
    mean	proc	
    	push bp
    	mov bp,sp
    	push bx					;保护寄存器
    	push cx
    	push dx
    	push si
    	push di
    	mov bx,[bp+4] 			;从堆栈取出偏移地址
    	mov cx,[bp+6] 			;从堆栈取数据个数
    	xor si,si				;SI保存求和的低16位值 用32位来存储求和结果,防止溢出
    	mov di,si				;DI保存求和的高16位值
    mean1:	mov ax,[bx]			;取出一个数据→AX
    	cwd						;AX符号扩展→DX
    	add si,ax				;求和低16位
    	adc di,dx				;求和高16位 注意是用adc指令
    	inc bx					;指向下一个数据
    	inc bx
    	loop mean1				;循环
    	mov ax,si
    	mov dx,di				;累加和在DX.AX
    	mov cx,[bp+6]			;数据个数在CX
    	idiv cx					;有符号数除法,求的平均值在AX中、余数在DX中
    	pop di					;恢复寄存器
    	pop si
    	pop dx
    	pop cx
    	pop bx
    	pop bp
    	ret
    mean	endp
    end
    
    展开全文
  •  5 宏子程序的区别  9.2 宏参数的特殊运算符  1 连接运算符  2 字符串整体传递运算符  3 字符转义运算符  4 计算表达式运算符  9.3 宏有关的伪指令  1 局部标号伪指令  2 取消宏定义伪指令  3 ...
  •  5 宏子程序的区别  9.2 宏参数的特殊运算符  1 连接运算符  2 字符串整体传递运算符  3 字符转义运算符  4 计算表达式运算符  9.3 宏有关的伪指令  1 局部标号伪指令  2 取消宏定义伪指令  3 ...
  •  5 宏子程序的区别  9.2 宏参数的特殊运算符  1 连接运算符  2 字符串整体传递运算符  3 字符转义运算符  4 计算表达式运算符  9.3 宏有关的伪指令  1 局部标号伪指令  2 取消宏定义伪指令  3 ...
  •  5 宏子程序的区别  9.2 宏参数的特殊运算符  1 连接运算符  2 字符串整体传递运算符  3 字符转义运算符  4 计算表达式运算符  9.3 宏有关的伪指令  1 局部标号伪指令  2 取消宏定义伪指令  3 ...
  •  5 宏子程序的区别  9.2 宏参数的特殊运算符  1 连接运算符  2 字符串整体传递运算符  3 字符转义运算符  4 计算表达式运算符  9.3 宏有关的伪指令  1 局部标号伪指令  2 取消宏定义伪指令  3 ...
  •  5 宏子程序的区别  9.2 宏参数的特殊运算符  1 连接运算符  2 字符串整体传递运算符  3 字符转义运算符  4 计算表达式运算符  9.3 宏有关的伪指令  1 局部标号伪指令  2 取消宏定义伪指令  3 ...
  • 3.1.2 Dalvik虚拟机Java虚拟机的区别 3.1.3 Dalvik虚拟机是如何执行程序的 3.1.4 关于Dalvik虚拟机JIT(即时编译) 3.2 Dalvik汇编语言基础为分析Android程序做准备 3.2.1 Dalvik指令格式 3.2.2 DEX文件反汇编工具...
  • 揭秘数据解密关键技术

    热门讨论 2011-11-20 21:49:11
    1.9.2 数据传送指令MOV、XCHG、PUSH、POP 1.9.3 地址传送指令 1.9.4 算数运算指令 1.9.5 逻辑运算指令 1.9.6 移位指令 1.9.7 条件转移指令 1.9.8 函数调用指令 1.1 0函数调用约定 1.1 0.1 3种常用调用约定 1.1 0.2...
  • DSP接口电路设计编程

    热门讨论 2009-09-26 11:30:23
     8.1 ADSP 21160早期SHARC DSP的区别  8.1.1 总体功能上的区别  8.1.2 第二套运算核(PEy)  8.1.3 两套运算部件  8.1.4 单指令多数据(SIMD)  8.1.5 循环缓冲模式  8.1.6 寄存器的广播式加载模式  8.1.7 ...
  •  4.3.5 移位与循环移位指令  4.4 运算指令  4.4.1 数学运算指令  4.4.2 逻辑运算指令  4.5 字符串指令  4.5.1 字符串基本指令  4.5.2 字符串转换指令  4.6 程序控制指令  4.6.1 程序控制基本指令 ...
  • 汇编语言教程

    2015-12-29 14:44:50
     5 宏子程序的区别  9.2 宏参数的特殊运算符  1 连接运算符  2 字符串整体传递运算符  3 字符转义运算符  4 计算表达式运算符  9.3 宏有关的伪指令  1 局部标号伪指令  2 取消宏定义伪指令  3 ...
  • 流水灯 1. 宏定义 typedef uchar =unsigned char 他是预处理指令,不是语句 常用典型语句 宏定义是用已有类型取别名 #define unit unsigned int//无符号整形 ...循环移位函数左移和右移运算符的区别 ...

    流水灯

    1 宏定义 typedef

    uchar =unsigned char
    他是预处理指令,不是语句
    常用典型语句
    宏定义是用已有类型取别名

    #define unit unsigned int//无符号整形
    #define uchar unsigned char//无符号字符型
    
    

    有时我们也可以用typedef关键字来取别名,加分号

    2.定义函数

    在这里插入图片描述
    在你自定义函数的时候,如果你写在main函数前面,那么不会有错误
    如果写在main函数后面,那么你需要在前面声明,并记得加分号。

    `3.循环位移函数

    左移 -crol-
    右移 -cror-
    标准库函数 intrins.h

    在这里插入图片描述

    4. 循环移位函数与左移和右移运算符的区别

    在这里插入图片描述

    5.程序

    #include <reg52.h>
    #include <intrins.h>
    
    #define uint unsigned int
    #define uchar unsigned char
    
    uchar temp;
    void delay(uint z)
    {uint x,y;
    	for(x=z;x>0;x--)
    		for(y=114;y>0;y--);
    	
    }
    void main()//main函数自己会循环
    {
    	
    	temp=0xfe;
    	P1=temp;//1111 1110
    	
    	while(1)
    	{
    		temp=_crol_ (temp,1);
    		P2=temp;
    		delay(100);
    	}
    
    }
    
    

    矩阵键盘

    在这里插入图片描述
    这里 我们在进行行扫描时,将行线全部给1,列线全部给0,如果按下键盘联通,那高位也会被拉低成0,。
    列扫描时,将行线全部给0,列线全部给1,如果按下键盘联通,那高位也会被拉低成0,
    将对应的二进制换成十六进制,加起来是一个唯一的数字来确定是按下了哪一个按键。

    程序

    实验现象:下载程序后数码管显示0,按下矩阵按键上的按键显示对应的数字
    		 
    注意事项:										
    
    										  
    **************************************************************************************
    
    */
    #include "reg52.h"			 //此文件中定义了单片机的一些特殊功能寄存器
    
    typedef unsigned int u16;	  //对数据类型进行声明定义
    typedef unsigned char u8;
    
    #define GPIO_DIG P0//通用IO口,就是普通的输入输du出引zhi脚。,数码管连接P0口
    #define GPIO_KEY P1//矩阵键盘用P1口。矩形按键控制数码管
    
    
    u8 KeyValue;	没有赋值,默认初始值是0//用来存放读取到的键值
    
    //共阳
    u8 code smgduan[17]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,
    					0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e};//显示0~F的值
    
    /*******************************************************************************
    * 函 数 名         : delay
    * 函数功能		   : 延时函数,i=1时,大约延时10us
    *******************************************************************************/
    void delay(u16 i)
    {
    	while(i--);	
    }
    
    /*******************************************************************************
    * 函 数 名         : KeyDown
    * 函数功能		   : 检测有按键按下并读取键值
    * 输    入         : 无
    * 输    出         : 无
    *******************************************************************************/
    void KeyDown(void)
    {
    	char a=0;
    	GPIO_KEY=0x0f;//行扫描
    	if(GPIO_KEY!=0x0f)//读取按键是否按下
    	{
    		delay(1000);//延时10ms进行消抖
    		if(GPIO_KEY!=0x0f)//再次检测键盘是否按下
    		{	
    			//测试列
    			GPIO_KEY=0X0F;重点,看似这里又重新定了,但是在你按下按键的时候大约需要20ms,GPIO_KEY的值会因为你的按下而在此改变
    			switch(GPIO_KEY)这个会确定是哪一行
    			{
    				case(0X07):	KeyValue=0;break;
    				case(0X0b):	KeyValue=1;break;
    				case(0X0d): KeyValue=2;break;
    				case(0X0e):	KeyValue=3;break;
    			}
    			//测试行
    			GPIO_KEY=0XF0;//列扫描
    			重点,看似这里又重新定了,但是在你按下按键的时候大约需要20ms,GPIO_KEY的值会因为你的按下而在此改变。代码运行的速度是很快的
    			当你松手之后,他会通过上拉电阻回到初始状态
    			
    			switch(GPIO_KEY)
    			{
    		case(0X70):	KeyValue=KeyValue;break;
    		case(0Xb0):	KeyValue=KeyValue+4;break;
    		case(0Xd0): KeyValue=KeyValue+8;break;
    	case(0Xe0):KeyValue=KeyValue+12;break;
    			}
    			
    		}
    	}
    	while((a<50)&&(GPIO_KEY!=0xf0))	 //检测按键松手检测
    	{
    		delay(100);
    		a++;
    	}
    }
    
    
    /*******************************************************************************
    * 函 数 名       : main
    * 函数功能		 : 主函数
    * 输    入       : 无
    * 输    出    	 : 无
    *******************************************************************************/
    void main()
    {	
    
    	while(1)
    	{	
    		KeyDown();		   //按键判断函数
    		GPIO_DIG=~smgduan[KeyValue];	  //
    	}		
    }
    

    在这里插入图片描述

    蜂鸣器

    在这里插入图片描述
    在这里插入图片描述P23和VCC都是5v,那么电路处于截止状态,蜂鸣器无法工作,当P23=0,则饱和接通。
    在这里插入图片描述
    在这里插入图片描述
    注释:p23不能直接连接蜂鸣器,单片机只适合用来做控制,不是功率器件,不适合驱动功率器件。

    今天真是当头一棒,我要让蜂鸣器工作,可是我很正确的在isp上打开对应的hex文件,可是为蛇魔每次竟然还出现流水灯,疯了,真是烦人,本来我要问一个大佬,后来赶紧撤回来,这种事也问人家,真的是太依赖人家了,后来,我就问客服,客服让我加了技术人员,确信我的蜂鸣器接口是P1。5.后来我终于知道了,通过观察isp的程序文件窗口,发现惊人一幕,和一个有流水灯的文件一样,我大吃一惊,虽然也不知道为啥,可能是因为在同一个项目里,受到了干扰。哎,太懒了。然后又规规矩矩创建了一个新的项目,就成功了,蜂鸣器的声音侦听难听点。差不多是噪音。。。呵呵呵。7.21记。

    #include "reg52.h"			 //此文件中定义了单片机的一些特殊功能寄存器
    #include<intrins.h>		//因为要用到左右移函数,所以加入这个头文件
    
    typedef unsigned int u16;	  //对数据类型进行声明定义
    typedef unsigned char u8;
    
    sbit beep=P1^5;	   
    
    /*******************************************************************************
    * 函 数 名         : delay
    * 函数功能		   : 延时函数,i=1时,大约延时10us
    *******************************************************************************/
    void delay(u16 i)
    {
    	while(i--);	
    }
    
    /*******************************************************************************
    * 函 数 名       : main
    * 函数功能		 : 主函数
    * 输    入       : 无
    * 输    出    	 : 无
    *******************************************************************************/
    void main()
    {	
    	while(1)
    	{	
    		beep=~beep;
    		delay(500); //100时延时大约1ms   通过修改此延时时间达到不同的发声效果	
    	}
    }
    
    

    数码表

    工作原理

    在这里插入图片描述
    在这里插入图片描述
    a接P0.0 低位 dp(点点)接P0.7高位
    将对应8位2进制转换成16进制,高低位不要看搞错
    在这里插入图片描述
    在这里插入图片描述
    静态数码管需要用64 8乘8 个I/O口 太费了

    锁存器

    在这里插入图片描述

    上拉电阻

    在这里插入图片描述

    锁存器与数码管的连接

    在这里插入图片描述

    A/D电路转换

    A代表连续,D代表不连续
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    此处我来讲述逐次逼近式ADC转换原理,设veef为5v,vin为3.75v,DA转化器和下面的寄存器都是8位,我们给DA的第一位赋1,把VEEF的一班拿来比较,2.5<3.75,那么下面对应第一位赋1,然后再加上现在的一半 即2.5+1.25=3.75,两面相等,下面仍然赋1,再加现在的一半,大于3.75,后面将都大。下面对应1100 0000
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    AD DA应用
    DA
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

    串口通信

    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    同步通信就是一直不断地发送信息,源源不断。异步通信就是一帧一帧的发,发了一帧以后,你可以随便停一会(多长时间任意),然后再发下一帧。
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

    比特率

    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在听他一讲,我懂了就是啥呢,你的数据线越长,那么分布电容和电感越大,这些会形成滤波电路,吸收掉你的信号
    注释:分布电容/寄生电容是由电气特性产生的

    (不)可位寻址

    可位寻址
    SM0=1
    不可位寻址
    SM0=0x01

    在这里插入图片描述
    在这里插入图片描述
    REN TI RI
    在这里插入图片描述

    比特率的计算

    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    经计算如果想要产生9600的比特率,需要TH1赋值0xDF 还有在这里的DFH 是什么意思呢 前面就是0xDF 后面代表hex十六进制 在1 0 工作方式2 8位这种定时器情况下TH1溢出后,会直接从TL1里面赋值,所以把TL1也写成0xDF。

    在这里插入图片描述

    在这里插入图片描述
    在这里插入图片描述
    小tip: 高四位是定时器1,低四位是定时器0.
    在这里插入图片描述
    在这里插入图片描述
    通信串口初始化

    void UsartInt()
    {
    
     1. List item
    
    1.TMOD=0x20;//0010 0000*确定计时器工作方式*,前四位定时器1,且工.作方式2 8位自动装载
    2,TH1=0xF3;//*9600比特率 计算初值*
    3。TL1=0xF3;//自动装载保持相同
    
    4.PCON=0x80;// *确定是否倍增*PCON的最高位是SCON 只有这一位和串口通信有关  1000 0000 2的1次方,倍增 
    
    }
    

    在这里插入图片描述

    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    实践开始,上面的小助手已经淘汰了,下面这个才是新版的
    在这里插入图片描述
    注意:
    在这里插入图片描述
    在这里插入图片描述
    真是内心激动,又解决了一个问题,谢谢技术员们了,而且很吃惊,我这个串口是UCB串口。emmmm
    我在程序里让第一个灯亮起来虽然亮灯没啥,但是我用通信串口做成的,很开心 今天尽忙活这些了。
    附图

    在这里插入图片描述

    感觉完成作业又进了一步。详细请看
    我的单片机作业

    AD转换

    在这里插入图片描述

    #include <string.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <windows.h>
    #include <conio.h>
    
    
    /************************结构体**************************/
    typedef struct student
    {
        char sushenum[40];//宿舍号
        char bednum[40];//床位数
        char name[40];//姓名
        char id[40];//学号
        char tel[40];//电话
        char masname[40];//寝室长姓名
        char masid[40];//寝室长学号
        char mastel[40];//寝室长电话
    }stu;//学生信息
    typedef struct  user
    {
        char usercode[30];//用户密码
        char userid[30];//用户账号
        char grade[3];//权限级别
    }use;//用户信息
    /**********************函数声明***************************/
    void reg();//管理员界面
    void denglu();//登录
    void secret();//加密
    void create_accont();//创建账号
    void dele_accout();//删除账号
    void reget();//重置,更新
    void create();//输入学生信息
    void find();//查询住宿信息
    void findmat1();//按照宿舍长学号查询
    void findmat2();//按照宿舍长电话查询
    void findnum();//按照宿舍号查询
    void findmes();//按照住宿学生电话查找
    void changecode();//更改密码
    void getthrough();//浏览住宿信息
    void emptybed();//查询空床位
    void color();
    int main()
    {
     int a,b,c,d,e,f,g;
        reg();
    denglu();
        printf("|\t\t\t\t请选择用户属性,管理员请按1,普通用户请按2.\t\t\n");
    
        scanf("%d",&a);
    
        if(a==1)
        {printf("\t\t\t\t\t进入管理员模块\t\t\n");
    
        scanf("%d",&b);
        loop1: switch(b)
            {
            case 1:
            {
    
               printf("用户信息管理\n");
              printf("\t\t\t\t====================================\n");
               printf("\t\t\t\t1.创建账号\n");
               printf("\t\t\t\t2.删除账号\n");
               printf("\t\t\t\t3.重置密码\n");
    printf("\t\t\t\t====================================\n");
                scanf("%d",&c);
    
              loop2:  switch(c)
                {
                case 1:
                     create_accont();
                    break;
                case 2:
                    dele_accout();//删除账号
                    break;
                case 3:
                   changecode();
                    break;
                default:
                    printf("错误\n");
                    goto loop2;
                }
            }
    
    
            case 2:
               {
    
                printf("住宿信息管理\n");
    
                printf("1.输入学生住宿信息\n");
                printf("2.删除信息\n");
                printf("3.查询住宿信息\n");
    
                scanf("%d",&d);
    
            loop3: switch(d)
                {
            case 1:
               create();
    
                break;
            case 2:
                dele();
                break;
            case 3:
                find();
                break;
            default:
                    printf("错误\n");
                    goto loop3;
                }
               }
            default:
                printf("输入错误,请重新输入");
                goto loop1;
            }
        }
        if(a==2)
        {
            printf("进入普通用户模块\n");
            printf("1.更改密码\n");
            printf("2.查找\n");
            printf("3.浏览\n");
            printf("4.查询空床位\n");
    
            scanf("%d",&e);
          loop4:  switch(e)
            {
            case 1:
                changecode();
                break;
            case 2:
                find();
                break;
            case 3:
                getthrough();
                break;
            case 4:
                emptybed();
                break;
            default:
                printf("输入错误,请重新输入");
                goto loop4;
            }
    
        }
    }
    void create()
    {FILE *fp;
    int i,n;
     stu inform[30];
    if((fp=fopen("st.txt","w"))==NULL)
    {
    printf("文件无法打开\n");
    exit(0);
    
    }
    printf("输入要输入的学生人数\n");
    scanf("\t\t%d\n",&n);
    printf("\t宿舍号 床位数 姓名 学号 电话 寝室长姓名 寝室长学号 寝室长电话\t\n");
    
    
    for(i=0;i<n;i++)
    {printf("\t\t\t==================================================\n");
        scanf("%s %s %s %s %s %s %s\n",inform[i].sushenum,inform[i].bednum,inform[i].name,
              inform[i].id,inform[i].tel,inform[i].masname,inform[i].masid,inform[i].mastel);
    
    }
    
    for(i=0;i<n;i++)
    {
    fprintf(fp,"%s %s %s %s %s %s %s\n",inform[i].sushenum,inform[i].bednum,inform[i].name,
            inform[i].id,inform[i].tel,inform[i].masname,inform[i].masid,inform[i].mastel);
    
    }
    fclose(fp);
    printf("信息录入成功。\n");
    
    
    
    }
    void dele()
    {FILE *fp;
    stu inform[40],xinxi;
    char shan[40];
    int i,n,flag;
    printf("显示所有姓名以及学号:\n");
    if((fp=fopen("st.txt","r"))==NULL)
    {
        printf("文件无法打开。\n");
        exit(0);
    }
    while(!feof(fp))
    {
    
    fscanf(fp,"%s %s %s %s %s %s %s",inform[i].sushenum,inform[i].bednum,inform[i].name,
            inform[i].id,inform[i].tel,inform[i].masname,inform[i].masid,inform[i].mastel);
    printf("%s %s\n",inform[i].name,inform[i].id);
     i++;
    }
    n=i;
    fclose(fp);
        loop6:  printf("输入要删除的学号\n");
    scanf("%s",shan);
    flag=2;
      for(i=0;i<n;i++)
      {
          if(strcmp(shan,inform[i].id)==0)
          {printf("找到对应信息,将删除该信息。\n");
          flag=1;
          break;
    
    
          }
      }
      if(flag!=1)
      {
          printf("没有找到相应的信息。\n");
          goto loop6;
      }
    
          for(int j=i;j<n;j++)
          {
              inform[j]=inform[j+1];
    
          }
          printf("删除成功。\n");
          if((fopen("st.txt","w"))==NULL)
          {
              printf("文件无法打开");
              exit(0);
    
    
          }
          for(i=0;i<n-1;i++)
          {printf("%s %s %s %s %s %s %s",inform[i].sushenum,inform[i].bednum,inform[i].name,
            inform[i].id,inform[i].tel,inform[i].masname,inform[i].masid,inform[i].mastel);
            fprintf(fp,"%s %s %s %s %s %s %s",inform[i].sushenum,inform[i].bednum,inform[i].name,
            inform[i].id,inform[i].tel,inform[i].masname,inform[i].masid,inform[i].mastel);
    
          }
          printf("新的信息输入完成。\n");
          fclose(fp);
    
      }
    void reget()
    {
        FILE *fp;
        int i,n,flag;
        stu inform[22],xinxi;
        char xiugai[22];
        flag=0;
        if((fopen("st.txt","w"))==NULL)
        {
            printf("文件无法打开。\n");
    
        }
        while(!feof(fp))
        {
            fscanf(fp,"%11s %5s %11s %11s %11s %11s %11s",inform[i].sushenum,inform[i].bednum,inform[i].name,
            inform[i].id,inform[i].tel,inform[i].masname,inform[i].masid,inform[i].mastel);
            printf("%11s %11s",inform[i].name,inform[i].id);
            i++;
        }
        n=i;
       loop7: printf("输入想要修改的学号,以便删除对应信息。\n");
        scanf("%s",xiugai);
        printf("输入你想重置的信息。\n");
         scanf("%11s %5s %11s %11s %11s %11s %11s",xinxi.sushenum,xinxi.bednum,xinxi.name,
            xinxi.id,xinxi.tel,xinxi.masname,xinxi.masid,xinxi.mastel);
        for(i=0;i<n;i++)
        {
            if((xiugai,inform[i].id)==0)
            {   flag=1;
                printf("正在重置你所想修改的信息。。。。。。。\n");
                strcpy(inform[i].sushenum,xinxi.sushenum);
                strcpy(inform[i].bednum,xinxi.bednum);
                strcpy(inform[i].name,xinxi.name);
                strcpy(inform[i].id,xinxi.id);
                strcpy(inform[i].tel,xinxi.tel);
                strcpy(inform[i].masid,xinxi.masid);
                strcpy(inform[i].masname,xinxi.masname);
                strcpy(inform[i].mastel,xinxi.mastel);
                printf("修改重置完成。将该信息输出检查是否成功\n");
                printf("%11s %5s %11s %11s %11s %11s %11s",inform[i].sushenum,inform[i].bednum,inform[i].name,
            inform[i].id,inform[i].tel,inform[i].masname,inform[i].masid,inform[i].mastel);
                i++;
                break;
            }
        }
           if(flag==0)
    
            {
                printf("没有找到相应信息。\n");
                 goto loop7;
            }
    
           for(i=0;i<n;i++)
           {
               fprintf("%11s %5s %11s %11s %11s %11s %11s",inform[i].sushenum,inform[i].bednum,inform[i].name,
            inform[i].id,inform[i].tel,inform[i].masname,inform[i].masid,inform[i].mastel);
    
           }
           fclose(fp);
    
    
        }
    void create_accont()
    {
        FILE *fp;
        int i=0,n;
        use usename[22],xinxi;
        char account[20],password[20];
        if((fp=fopen("ac.txt","r"))==NULL)
        {
            printf("文件无法打开。\n");
            exit(0);
        }
        printf("列举全部账号:\n");
        while(!feof(fp))
        {
            fscanf(fp,"%s %s\n",usename[i].userid,usename[i].usercode);
            printf("%s\n",usename[i].userid);
            i++;
        }
        fclose(fp);
        n=i;
        loop8:
            printf("输入要添加的账号:");
            scanf("%s",account);
            for(i=0;i<n;i++)
            {
                if(strcmp(usename[i].userid,account)==0)
                {
                    printf("该账号已经存在。请重新输入。\n");
                    goto loop8;
                }
            }
        printf("输入要添加账号的密码:");
        getchar();
        scanf("%s",password);
    
        strcpy(usename[i].userid,account);
        strcpy(usename[i].usercode,password);
        for(i=0;i<n+1;i++)
        {
            for(int j=i;j<n+1;j++)
            {
                if((strcmp(usename[i].userid,usename[j].userid))>0)
                xinxi=usename[i];
            usename[i]=usename[j];
            usename[j]=xinxi;
    
            }
        }
    
    
    if((fp=fopen("ac.txt","w"))==NULL)
    {
        printf("文件打开错误。\n");
        exit(0);
    }
    for(i=0;i<n+1;i++)
    {
        fprintf(fp,"%s %s\n",usename[i].userid,usename[i].usercode);
    
    }
    fclose(fp);
    system("cls");
    printf("账号录入成功。\n");
    }
    
    void dele_accout()//删除账号
    {
        system("cls");
    FILE *fp;
    int i,n,k=0;
    use user[22];
    char account[22],password[22];
    printf("列举全部账号。\n");
    if((fopen("ac.txt","r"))==NULL)
    {
        printf("文件打开错误。\n");
        exit(0);
    }
    while(!feof(fp))
    {fscanf(fp,"%s %s\n",user[i].userid,user[i].usercode);
    printf("%s %s\n",user[i].userid);
    i++;
    
    
    }
    fclose(fp);
    n=i;
     loopb:printf("输入你想要删除的账号。\n");
    scanf("%s",account);
    for(i=0;i<n;i++)
    {
    
    if((strcmp(user[i].userid,account))==0)
    {   k=1;
        break;
    }
    
    }
    if(k!=1)
       {
    
       printf("无此账号!请重新输入!\n");
    goto loopb;
    }
        for(int j=i;j<n;j++)
    {
        user[j]=user[j+1];
    }
    system("cls");
    printf("删除成功。\n");
    
    
    
    if((fopen("ac.txt","r"))==NULL)
    {
        printf("文件打开错误。\n");
        exit(0);
    }
    for(i=0;i<n-1;i++)
    {
        fprintf(fp,"%s %s\n",user[i].userid,user[i].usercode);
    
    }
    printf("删除账号成功。\n");
    fclose(fp);
    }
    void find()
    {int choice;
    printf("\t\t请选择您以何种方式查找。输入1-4代表您的选择。\t\t\n");
    printf("\t\t1.按宿舍号查找。\t\t\n");
    printf("\t\t2.按寝室长电话查找。\t\t\n");
    printf("\t\t3.按寝室长电话查询。\t\t\n");
    printf("\t\t4.按住宿学生本人信息查询。\t\t\n");
    scanf("%d",&choice);
    
        switch(choice)
        {
            //case 1:printf("文件打开");
    
            case 1:findnum();//宿舍号
            case 2:findmat1();//宿舍长学号
            case 3:findmat2();//宿舍长电话
            case 4:findmes();//学生信息
        }
    }
    void findnum()
    {
        FILE *fp;
        stu inform[23];
        char sushehao[20];
        int i=0,k=0,n;
        if((fopen("st.txt","r"))==NULL)
    {
        printf("文件打开错误。!!!\n");
        exit(0);
    }
    
    
     while(!feof(fp))
        {
            fscanf(fp,"%11s %5s %11s %11s %11s %11s %11s",inform[i].sushenum,inform[i].bednum,inform[i].name,
              inform[i].id,inform[i].tel,inform[i].masname,inform[i].masid,inform[i].mastel);
    
            printf("%s\n",inform[i].sushenum);
            i++;
        }
        fclose(fp);
        n=i;
       loop9: printf("输入你要查找的宿舍号\n");
        scanf("%s",sushehao);
        for(i=0;i<n;i++)
        {
            if((strcmp(inform[i].sushenum,sushehao))==0)
            {     k=1;
                printf("找到对应宿舍号。\n");
                printf("%11s %5s %11s %11s %11s %11s %11s",inform[i].sushenum,inform[i].bednum,inform[i].name,
              inform[i].id,inform[i].tel,inform[i].masname,inform[i].masid,inform[i].mastel);
            }
    
        }
        if(k==0)
        {
            printf("没有找到对应宿舍号。\n");
            goto loop9;
        }
    }
    void findmat1()
    {
        FILE *fp;
        stu inform[23];
        char qszxh[20];
        int i=0,k=0,n;
        if((fopen("st.txt","r"))==NULL)
    {
        printf("文件打开错误。\n");
        exit(0);
    }
     while(!feof(fp))
        {
            fscanf(fp,"%11s %5s %11s %11s %11s %11s %11s",inform[i].sushenum,inform[i].bednum,inform[i].name,
              inform[i].id,inform[i].tel,inform[i].masname,inform[i].masid,inform[i].mastel);
    
            printf("||%s||\n",inform[i].masid);
            i++;
        }
        fclose(fp);
        n=i;
       loop10: printf("输入你要查找的寝室长学号\n");
        scanf("%s",qszxh);
        for(i=0;i<n;i++)
        {
            if((strcmp(inform[i].masid,qszxh))==0)
            {     k=1;
                printf("找到对应宿舍号。\n");
                printf("%11s %5s %11s %11s %11s %11s %11s",inform[i].sushenum,inform[i].bednum,inform[i].name,
              inform[i].id,inform[i].tel,inform[i].masname,inform[i].masid,inform[i].mastel);
            }
    
        }
        if(k==0)
        {
            printf("没有找到对应宿舍号。\n");
            goto loop10;
        }
    }
    void findmat2()
    {
        FILE *fp;
        stu inform[23];
        char qszdh[20];
        int i=0,k=0,n;
        if((fopen("st.txt","r"))==NULL)
    {
        printf("文件打开错误。\n");
        exit(0);
    }
     while(!feof(fp))
        {
            fscanf(fp,"%s %s %s %s %s %s %s",inform[i].sushenum,inform[i].bednum,inform[i].name,
              inform[i].id,inform[i].tel,inform[i].masname,inform[i].masid,inform[i].mastel);
    
            printf("||%s||\n",inform[i].masid);
            i++;
        }
        fclose(fp);
        n=i;
       loop11: printf("输入你要查找的寝室长电话\n");
        scanf("%s",qszdh);
        for(i=0;i<n;i++)
        {
            if((strcmp(inform[i].mastel,qszdh))==0)
            {     k=1;
                printf("找到对应宿舍长电话。\n");
                printf("%11s %5s %11s %11s %11s %11s %11s",inform[i].sushenum,inform[i].bednum,inform[i].name,
              inform[i].id,inform[i].tel,inform[i].masname,inform[i].masid,inform[i].mastel);
            }
    
        }
        if(k==0)
        {
            printf("没有找到对应宿舍长电话。\n");
            goto loop11;
        }
    }
    void findmes()
    {
        FILE *fp;
        stu inform[23];
        char xsdh[20];
        int i=0,k=0,n;
        if((fopen("st.txt","r"))==NULL)
    {
        printf("文件打开错误。\n");
        exit(0);
    }
     while(!feof(fp))
        {
            fscanf(fp,"%11s %5s %11s %11s %11s %11s %11s",inform[i].sushenum,inform[i].bednum,inform[i].name,
              inform[i].id,inform[i].tel,inform[i].masname,inform[i].masid,inform[i].mastel);
    
            printf("||%s||\n",inform[i].tel);
            i++;
        }
        fclose(fp);
        n=i;
       loop12: printf("输入你要查找的寝室长电话\n");
        scanf("%s",xsdh);
        for(i=0;i<n;i++)
        {
            if((strcmp(inform[i].tel,xsdh))==0)
            {     k=1;
                printf("找到对应学生电话。\n");
                printf("%11s %5s %11s %11s %11s %11s %11s",inform[i].sushenum,inform[i].bednum,inform[i].name,
              inform[i].id,inform[i].tel,inform[i].masname,inform[i].masid,inform[i].mastel);
            }
    
        }
        if(k==0)
        {
            printf("没有找到对应学生电话。\n");
            goto loop12;
        }
    }
    void changecode()
    {system("cls");
        FILE *fp;
        use inform[23];
        char newcode[20],id;
        int i=0,k=0,n;
        if((fopen("ac.txt","r"))==NULL)
    {
        printf("文件打开错误。\n");
        exit(0);
    }
     while(!feof(fp))
        {
            fscanf(fp,"%s %s\n",inform[i].userid,inform[i].usercode);
    
            printf("||%s||\n",inform[i].userid);
            i++;
        }
        fclose(fp);
        n=i;
       loop14: printf("输入你要更改密码的账号。\n");
        scanf("%s",id);
        for(i=0;i<n;i++)
        {
            if((strcmp(inform[i].userid,id))==0)
            {     k=1;
                printf("找到对应账号。\n");
               printf("请输入你想设置的新密码。\n");
               scanf("%s",newcode);
               secret(newcode);
               strcpy(inform[i].usercode,newcode);
               break;
            }
    
    
        }
        if(k==0)
        {
            printf("没有找到对应账号。再此输入\n");
            goto loop14;
        }
    
    if((fopen("ac.txt","w"))==NULL)
    {
        printf("文件打开错误。\n");
        exit(0);
    }
    for(i=0;i<n;i++)
    {
        fprintf(fp,"inform[i].userid,inform[i].usercode");
    }
    fclose(fp);
    printf("密码修改成功,请重新登录。\n");
    main(4);
    }
    void getthrough()
    {system("cls");
        FILE *fp;
        stu inform[45];
    
        int i=0,n;
        if((fopen("st.txt","r"))==NULL)
    {
        printf("文件打开错误。\n");
        exit(0);
    }
     while(!feof(fp))
        {
            fscanf(fp,"%11s %5s %11s %11s %11s %11s %11s",inform[i].sushenum,inform[i].bednum,inform[i].name,
            inform[i].id,inform[i].tel,inform[i].masname,inform[i].masid,inform[i].mastel);
    
            printf("%11s %5s %11s %11s %11s %11s %11s",inform[i].sushenum,inform[i].bednum,inform[i].name,
            inform[i].id,inform[i].tel,inform[i].masname,inform[i].masid,inform[i].mastel);
            i++;
        }
        printf("一共有%d个学生。\n",i);
        fclose(fp);
    
    
    }
    void emptybed()
    {
    system("cls");
        FILE *fp;
        stu inform[23];
    char numa[20];
        int i=0,n,iden;
        if((fopen("st.txt","r"))==NULL)
    {
        printf("文件打开错误。\n");
        exit(0);
    }
    printf("宿舍号 床位号 姓名 学号 宿舍长姓名\n ");
     while(!feof(fp))
        {
            fscanf(fp,"%11s %5s %11s %11s %11s %11s %11s",inform[i].sushenum,inform[i].bednum,inform[i].name,
            inform[i].id,inform[i].tel,inform[i].masname,inform[i].masid,inform[i].mastel);
            printf("*************************************************************\n");
    
            printf("%11s %5s %11s %11s %11s\n",inform[i].sushenum,inform[i].bednum,inform[i].name,
            inform[i].id,inform[i].masname);
            i++;
        }
    printf("查询剩余空床位。\n");
    printf("\t\t=========================\n\t\t");
    printf("注释:每个宿舍6个人,本宿舍共120个宿舍,每层20个,按(楼层数+宿舍编号)标号\n\n");
    printf("输入要查询的宿舍号:");
       loop15: scanf("%s",numa);
    fscanf(fp,"%11s %5s %11s %11s %11s\n",inform[i].sushenum,inform[i].bednum,inform[i].name,
            inform[i].id,inform[i].masname);
            while(1)
            {
                if((strcmp(numa,inform[i].sushenum))==0)
                {
                    i++;
                }
            }
    if(i==6)
    {printf("该宿舍已经满员");
      goto loop15;
    }
    else
        printf("该宿舍还有%d个空余床位。\n",6-i);
    
    }
    void secret(char password[])
    {int i;
    for(i=0;i<strlen(password);i++)
    {
        password[i]+=20;
    }
    
    }
    void reg()
    {
        printf("\n\n");
        printf("\t\t\t\t.........................................................\n");
        color(10);
    
    printf("\t\t\t\t========================================================\n");
        printf("\t\t\t\t\t欢  迎  使  用  宿  舍  管  理  系  统\t\t\n ");
        printf("\t\t\t\t=========================================================\n");
        printf("     \t\t\t\t*\t\t\t1-系统管理员\t\t\t*\n");
        printf("     \t\t\t\t*\t\t\t2-普通用户\t\t\t*\n");
        printf("\t\t\t\t=========================================================\n");
    
    }
    void color(int x) //设置字体颜色
    {
    if(x>=0 && x<=15)
    SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), x);
    else
    SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 7);
    }
    void denglu()
    {
        char iid[20],password[22];
    FILE *fp;
    use inform[23];
    if((fp=fopen("ac.txt","r"))==NULL)
    {
        printf("File open error!\n");
    }
    printf("全部账号如下:\n");
    int i=0,n=0;
         while(!feof(fp))
        {
            fscanf(fp,"%s %s\n",inform[i].userid,inform[i].usercode);
    
            printf("\t\t%s\n",inform[i].userid);
            i++;
        }
        fclose(fp);
         printf("请输入账号>>");
       loop16: scanf("%s",iid);
        int flag=0;
        n=i;
    for(i=0;i<n;i++)
    {
        if((strcmp(inform[i].userid,iid))==0)
        {printf("请输入密码>>");
       loopa: scanf("%s",password);
    
        flag=1;
        }
    }
    if(flag==0)
    {
        printf("该账号不存在,请重新输入。\n");
        goto loop16;
    }
    
         if((strcmp(password,"123456"))==0)
           {
               printf("登录成功\n");
           }
           else
           {
               printf("密码错误,请重新输入密码。\n");
               goto loopa;
           }
    
    }
    
    
    展开全文
  • 汇编语言学习大全

    2011-10-08 22:56:17
     5 宏子程序的区别  9.2 宏参数的特殊运算符  1 连接运算符  2 字符串整体传递运算符  3 字符转义运算符  4 计算表达式运算符  9.3 宏有关的伪指令  1 局部标号伪指令  2 取消宏定义伪指令  3 ...
  •  5 宏子程序的区别  9.2 宏参数的特殊运算符  1 连接运算符  2 字符串整体传递运算符  3 字符转义运算符  4 计算表达式运算符  9.3 宏有关的伪指令  1 局部标号伪指令  2 取消宏定义伪指令  3 ...
  •  5 宏子程序的区别  9.2 宏参数的特殊运算符  1 连接运算符  2 字符串整体传递运算符  3 字符转义运算符  4 计算表达式运算符  9.3 宏有关的伪指令  1 局部标号伪指令  2 取消宏定义伪指令  3 ...
  • 80x86汇编语言教程

    2011-01-26 21:36:37
     5 宏子程序的区别  9.2 宏参数的特殊运算符  1 连接运算符  2 字符串整体传递运算符  3 字符转义运算符  4 计算表达式运算符  9.3 宏有关的伪指令  1 局部标号伪指令  2 取消宏定义伪指令  3 ...
  •  5 宏子程序的区别  9.2 宏参数的特殊运算符  1 连接运算符  2 字符串整体传递运算符  3 字符转义运算符  4 计算表达式运算符  9.3 宏有关的伪指令  1 局部标号伪指令  2 取消宏定义伪指令  3 ...
  •  5 宏子程序的区别  9.2 宏参数的特殊运算符  1 连接运算符  2 字符串整体传递运算符  3 字符转义运算符  4 计算表达式运算符  9.3 宏有关的伪指令  1 局部标号伪指令  2 取消宏定义伪指令  3 ...
  •  5 宏子程序的区别  9.2 宏参数的特殊运算符  1 连接运算符  2 字符串整体传递运算符  3 字符转义运算符  4 计算表达式运算符  9.3 宏有关的伪指令  1 局部标号伪指令  2 取消宏定义伪指令  3 ...
  •  5 宏子程序的区别  9.2 宏参数的特殊运算符  1 连接运算符  2 字符串整体传递运算符  3 字符转义运算符  4 计算表达式运算符  9.3 宏有关的伪指令  1 局部标号伪指令  2 取消宏定义伪指令  3 ...
  •  5 宏子程序的区别  9.2 宏参数的特殊运算符  1 连接运算符  2 字符串整体传递运算符  3 字符转义运算符  4 计算表达式运算符  9.3 宏有关的伪指令  1 局部标号伪指令  2 取消宏定义伪指令  3 ...
  •  5 宏子程序的区别  9.2 宏参数的特殊运算符  1 连接运算符  2 字符串整体传递运算符  3 字符转义运算符  4 计算表达式运算符  9.3 宏有关的伪指令  1 局部标号伪指令  2 取消宏定义伪指令  3 中止宏...
  •  5 宏子程序的区别  9.2 宏参数的特殊运算符  1 连接运算符  2 字符串整体传递运算符  3 字符转义运算符  4 计算表达式运算符  9.3 宏有关的伪指令  1 局部标号伪指令  2 取消宏定义伪指令  3 ...
  •  5 宏子程序的区别  9.2 宏参数的特殊运算符  1 连接运算符  2 字符串整体传递运算符  3 字符转义运算符  4 计算表达式运算符  9.3 宏有关的伪指令  1 局部标号伪指令  2 取消宏定义伪指令  3 ...
  • 汇编语言教程.chm

    2010-12-07 08:24:56
     5 宏子程序的区别  9.2 宏参数的特殊运算符  1 连接运算符  2 字符串整体传递运算符  3 字符转义运算符  4 计算表达式运算符  9.3 宏有关的伪指令  1 局部标号伪指令  2 取消宏定义伪指令  3 ...
  •  5 宏子程序的区别  9.2 宏参数的特殊运算符  1 连接运算符  2 字符串整体传递运算符  3 字符转义运算符  4 计算表达式运算符  9.3 宏有关的伪指令  1 局部标号伪指令  2 取消宏定义伪指令  3 ...

空空如也

空空如也

1 2 3 4
收藏数 73
精华内容 29
关键字:

循环指令与移位指令的区别