资源描述
微机原理与接口技术期末复习-程序专题-测控122班委会编辑
编程指令分析
1、求累加器AX和寄存器BX中两个无符号数之差的绝对值,结果送外设2000H
MOV CX,AX ;保存AX
SUB AX,BX ; AX-BX AX变了
JC AA ;CF=1,最高位有借位,AX<BX,跳转
BB:MOV DX,2000H ; 外部地址
OUT DX,AX ;
HLT ;CPU进入暂停状态。
AA:SUB BX,CX ;BX=( BX-CX(AX) )
MOV AX,BX
JMP BB
3、若在某数据段2000H开始的48个单元中,存放着某班48个同学的数学课考试成绩。试编写程序找出该班的最高分,将其置于BL中
MOV CX,2FH
MOV SI,2000H
MOV BL,[SI]
BB:INC SI
MOV AL,[SI]
SUB AL,BL
JC AA ;有借位,AL<BL
MOV BL,[SI] ;AL>=BL,BL=AL
AA:LOOP BB
HLT
4、编程序将内存从4000:0000H到4000:00FFH的每个单元中均写入55H
MOV AX,4000H
MOV ES,AX ;段地址赋初值
MOV CX,100H ;00FFH=100D
MOV DI,0H ;
MOV AL,55H
CLD
REP STOSB ;
HLT
(若改为字节操作,则“100H”→128D;“AL,55H”→AX,5555H;STOSB→STOSW)
5、从外设500H单元中读取一个字节M,判断其值是否在70H和80H之间,即70H≤M<80H。如果M≥80H,则送0FFH给外设端口502H;如果M<70H,则送00H给外设端口502H;如果70H≤M<80H,则送88H给外设端口502H
START:MOV DX,500H ;端口地址
IN AL,DX ;从外部端口输入内容到AL
CLC ;清零借位标志CF
CMP AL,70H ;AL-70H
JC LP1 ;CF=1有借位,AL<70H,转LP1
CMP AL,80H ;AL>=70H,AL-80H
JC LP2 ;70H<AL<80H,转LP2
MOV AL,0FFH ;AL>=80H,AL=0FFH(第一个16进制数为字母的,前面加0,以区别程序中的变量)
LP3:MOV DX,502H ;输出端口地址赋到DX中
OUT DX,AL ;将结果传送到外部端口
HLT
LP1:MOV AL,00H
JMP LP3
LP2:MOV AL,88H
JMP LP3
6、设X、Y、Z是三个16位有符号数,存放在@DATA的数据段,寻找最大数,存到MAX单元
START:MOV AX,@DATA
MOV DS,AX ;DS段初始化
MOV AX,X
CMP AX,Y
JGE L1 ;X>=Y,转L1
MOV AX,Y ;X<=Y,大数Y赋到AX中
L1:CMP AX,Z ;AX-Z,
JGE L2 ;AX>=Z,转L2
MOV AX,Z ;AX<Z,大数Z赋到AX中
L2:MOV MAX,AX ;最大数赋到MAX存储单元
7、若在3000:3000H和3000:3001H单元有两个无符号数,编一个程序比较它们的大小,把大的数放在3000:3002H单元
START:MOV AX,3000H
MOV DS,AX ;段地址赋初值
MOV AL,[3000H] ;低地址单元内容 AL←(DS×16+3000)
CMP AL,[3001H] ;两内容相比较
JAE L ;(above and equal)AL>=高
XCHG AL,[3001H] ;AL<高的,交换
L:MOV [3002H],AL
HLT
8、设X、Y、Z、W均为存放16位带符号数单元的地址。编写程序段完成下列操作
Z←W+(Z-X)
MOV AX,Z
SUB AX,X ;AX←Z-X
MOV DX,W
ADD DX,AX ;DX←DX+AX
MOV Z,DX Z ← DX
HLT
9、编写汇编简易程序段,若自BLOCK开始的内存缓冲区中,有100个带符号的数(字为单位),希望找到其中最大的一个值,并将它放到MAX单元中。
MOV CX,99 ;0-99个带字符的数
MOV BX,0 ;起始偏移地址
MOV MAX,BLOCK[BX] ;第一个数放入MAX中
LOOP1: MOV AX,BLOCK[BX] ;BLOCK[BX]放入到AX里
CMP AX,BLOCK[BX+2] ;两个数进行比较
JGE NEXT ;第一个数>=第二个数,跳到NEXT
MOV MAX,BLOCK[BX+2] ;第二个数大,就放到MAX里
NEXT: ADD BX,2 ;每次加2
LOOP LOOP1
★10、试用无条件传送方式分别从1000H、1002H端口读入2个字节后,屏蔽每个字节的低四位,然后将其分别送当前数据段2000H、2001H单元和端口3000H、3002H
MOV DX,1000H
IN AL,DX
AND AL,0F0H
MOV [2000H],AL
MOV DX,3000H
OUT DX,AL
MOV DX,1002H
IN AL,DX
AND AL,0F0H
MOV [2001H],AL
MOV DX,3002H
OUT DX,AL
HLT
(若改为1000H~10FFH 256
2000H~20FFH 256
3000H~30FFH 256
则 MOV CX,100H ;总字节数
MOV BX,2000H ;目的地址(当前数据段)
MOV SI,1000H ;原数据地址(也在外部端口)
MOV DI,3000H ;目的地址(外部端口)
L:MOV DX,SI
IN AL,DX ;从外部端口输入数据到AL
AND AL,0F0H ;保留高四位,低四位清零
MOV [BX],AL ;处理后的数据送当前数据段地址
MOV DX,DI
OUT DX,AL ;处理后的数据传送到外部端口地址
INC BX
INC SI
INC DI
LOOP L
HLT
★11、试用无条件传送方式将内存数据段中偏移地址为3500H~3502H单元的内容依次送225H~227H端口
MOV AL,[3500H] ;内容的内存地址,传送的是内容
MOV DX,225H ;目的地址(外部端口)
OUT DX,AL ;传送到外部端口
MOV AL,[3501H]
MOV DX,226H
OUT DX,AL
MOV AL,[3502H]
MOV DX,227H
OUT DX,AL
HLT
(若改为5000H~50FFH→200H~2FFH
则 MOV SI,5000H ;原数据初始地址
MOV DX,200H ;目的端口地址
MOV CX,100H ;数据个数
L:MOV AL,[SI] ;
OUT DX,AL ;数据传输到外部端口
INC SI
INC DX
LOOP L
★12、设AX寄存器中存放一个16位二进制数,试编写一个程序,统计AX中“1”的个数,统计结果送AX中
MOV CX,0 ;计数器清零
LOOP:SUB AX,0 ;AL-0
JZ STP ;AL=0,跳转
SAL AX,1 ;算术左移一位(到CF里)
JNC NOD ;CF=0
INC CX ;CF=1,计数值加一
NOD:JMP LOOP
STP:HLT
13、设AX中有一个16位二进制数,试编写程序,统计AX中为“1”的位数,统计的结果送CX中,若为“1”的位数为偶数,则将数据55H写入AX
MOV CX,0 ;计数值清零
LOOP:SUB AX,0 ;AX-0
JZ STP ;AX=0,1的个数为0 ,是偶数,转STP
SAL AX,1 ;左移一位,最高位进CF
JNC NOD ;CF=0,最高位不是1,转NOD
INC CX ;最高位是1,计数值加1
NOD:JMP LOOP
STP:RCR CX,1
JC STOP
MOV AX,55H
STOP:HLT
14、若在DAT开始的顺序50个单元中,存放着某班50个同学的数学课考试成绩。试编写程序求该班这门课的平均成绩
MOV CX,50 ;计数初始值
MOV SI,DAT ;初始地址
XOR AX,AX ;累加器AX清零
L:ADD AL,[SI] ;从第一个开始相加放入AL(8位)中,2为十进制
ADC AH,0 ;取进位,放入AH中(进位值不会超过50(8位))
INC SI ;地址加一
LOOP L
MOV BL,50 ;除数
DIV BL ;取平均
HLT
(若改为500个同学,则“50” →500;“BL,50” →BX,500;“BL” →BX;“XOR AX,AX”后添加MOV DX,0;“ADC AH,0”后添加ADC DX,0)
MOV CX,500 ;计数初始值
MOV SI,DAT ;初始地址
XOR AX,AX ;累加器AX清零
MOV DX,0
L:ADD AL,[SI] ;从第一个开始相加放入AL(8位)中,2为十进制
ADC AH,0 ;取进位,放入AH中(进位值会超过99)超过8位2进制
ADC DX,0 ;再取进位(一位十进制)
INC SI ;地址加一
LOOP L
MOV BX,500 ;除数
DIV BX ;取平均
HLT
15、大小写字母转换
已知在以BUF为首地地址的字节存储区中,存放着一个以‘$’作结束标志的字符串,编写程序,显示该字符串,并要求将小写字母以大写字母形式显示出来。(小写a为61H,大写A为41H。)
STUCK SEGMENT
DB 200 DUP(0)
STUCK ENDS
DATA SEGMENT
BUF DB 'add AX,BX sub CX,10 MOV dx,1234h END$'
DATA ENDS
CODE SEGMENT
ASSUME CS:CODE,DS:DATA,SS:STUCK
BEGIN: MOV AX,DATA
MOV DS,AX ;数据段地址装填(堆栈段地址由系统装填)
LEA BX,BUF ;BUF(存储区域)首地址→BX
LOPA: MOV DL,[BX] ;直接寻址,内容→DL
CMP DL,'$' ;确定没有到最后一个内容
JE EXIT
CMP DL,'a' ;内容与‘a’比较
JB N ;DL<’a’
CMP DL,'z' ;内容与 ’z’ 比较
JA N ;DL>’z’
SUB DL,20H ;’a’<DL<’z’,为小写字母,DL-20H,变为大写
N: MOV AH,2 ;显示字符用DOS的2号功能调用
INT 21H ; 修改后的内容输出到显示器
INC BX ;地址值加1
JMP LOPA
EXIT: MOV AH,4CH ;返回DOS
INT 21H
CODE ENDS
END BEGIN
28.编写一个程序,求W=(X2-Y2)/ Z,设X、Y、均为一个8位无符号数,运算不考虑溢出。
分析:表达式改写为W=(X+Y)(X-Y)/Z,因为表达式简单,根据表达式运算次序来编写程序,由于运算不考虑溢出,所以不考虑(X+Y)>256情况。
解:程序清单如下:
STUCK SEGMENT PARA STACK
DW 20H DUP(0)
STUCK ENDS
DATA SEGMENT
DATX DB 80 ;假定X为80
DATY DB 50 ;定义Y的值
DATZ DB 5 ;定义Z的值
DATW DB ? ;定义保存计算结果的存储单元
DATA ENDS
CODE SEGMENT
ASSUME CS:CODE,DS:DATA,SS:STUCK
BEGIN:MOV AX,DATA
MOV DS,AX ;数据段地址装填(堆栈段地址由系统装填)
MOV AL,DATX ;取X
ADD AL,DATY ;计算(X+Y)→(AL)
MOV BL,DATX ;取X
SUB BL,DATY ;计算(X-Y)→(BL)
MUL BL ;计算AL×BL→(AX) 即(X+Y)×(X-Y)→(AX)
MOV CL,DATZ ;取Z
DIV CL ;计算AX/Z→AL即(X+Y)×(X-Y)/Z→AL
MOV DATW,AL ;保存结果
MOV AH,4CH ;返回DOS
INT 21H
CODE ENDS
END BEGIN
29.编写一个程序,实现键入任一个字符,显示其十进制的ASCⅡ码(例如:键入A,显示41H)。
分析:首先接受一个字符,其ASCⅡ码一定在0~255之间,把二进制的ASCH码转换为十进制后输出即可。转换的算法是:用该数除以100,商是二进制的百位;再把余数除以10,商是二进制的十位;余数是二进制的个位。二进制的百位、十位、个位加上30H即为字符的百位、十位、个位,然后输出即可。
解:程序清单如下:
CODE SEGMENT
ASSUME CS:CODE
START:MOV AH,1
INT 21H ;读一个按键
MOV AH,0 ;准备做AX/100,所以要把AH清0
MOV BL,100 ;除法指令不允许用立即数,把除数放在BL中
DIV BL ;除以100,商保存在AL中,余数保存在AH中(8位)
MOV CL,AL ;保存商,即百位数
ADD CL,30H ;把百位数转化成ASCⅡ码
MOV AL,AH ;取除以100的余数到BL中,作下一次的被除数
MOV AH,0 ;被除数高位部分清0
MOV BL,10 ;准备除数10
DIV BL ;除以10,商在AL中,余数在AH中
ADD AL,30H ;商是十位数,转换成ASCⅡ码 (0-9对应ASCⅡ码为30H-39H
ADD AH,30H ;把余数个位数转换成ASCⅡ码
MOV BX,AX ;用BX保存转换后的十位和个位数字
MOV AH,2 ;输出显示
MOV DL,13 ;回车的ASCLL
INT 21H ;输出回车
MOV DL,10
INT 21H ;输出换行符
MOV DL,CL ;输出百位数
INT 21H
MOV DL,BL ;输出十位数
INT 21H
MOV DL,BH ;输出个位数
INT 21H
MOV AH,4CH
INT 21H
CODE ENDS
END START
30.以BUF为首地址的内存单元中存有1~15的平方表。查表求X单元中数(在1~15之间)的平方值,并送回X单元。
分析:表是一种常见的数据结构,平方表是一个数据表,为便于查表,需要组织好表的结构,即表中的平方值按顺序存放。查表的方法是顺序查表法,以X为索引值,将索引值和平方表的首地址相加,其和作为表内偏移地址,取出相应X的平方值。
解:程序清单如下:
NAME EXAM3
DATA SEGMENT
BUF DB 1,4,9,16,25,36,49,64
DB 81,100,121,144,169,196,255
X DB 12 ;要查询的数,
DATA ENDS
STACK SEGMENT STACK ’STACK’
DB 100 DUP(?)
STACK ENDS
CODE SEGMENT
ASSUME CS:CODE,DS:DATA,SS:STACK ;段地址说明
START:MOV AX,DATA
MOV DS,AX ;数据段地址装填(堆栈段地址由系统装填)
MOV SI,OFFSET BUF ;取BUF(首地址)的偏移量
XOR AX,AX ;AX清0
MOV AL,X ;取X
DEC AL ;AL=AL-1,的偏移地址
ADD SI,AX ;X平方值的地址(距表首地址的偏移量)
MOV AL,[SI] ;取X的平方值
MOV X,AL
MOV AH,4CH
INT 21H ;返回DOS
CODE ENDS
END START
31.以BUF为首地址的内存单元中,存放若干个8位的带符号数,统计≥0的数的个数,并将结果存入RESULT字节单元中。
解:程序清单如下:
DATA SEGMENT
BUFF DB 1,-4,90,16,0,36,-49,-68
CNT EQU $-BUFF ;数据长度、符号数的总个数:末尾数据后的一个地址-首地址
RESULT DB ? ;定义结果存放空间
DATA ENDS
STACK SEGMENT PARA STACK
DB 100 DUP(?)
STACK ENDS
CODE SEGMENT
ASSUME CS:CODE,DS:DATA,SS:STACK ;段地址说明
START:MOV AX,DATA
MOV DS,AX ;数据段地址装填(堆栈段地址由系统装填)
LEA SI, BUFF ;取BUFF(首地址)的偏移量
MOV DL,0 ;DL清0
MOV CL,CNT ;取符号数的总个数,设置循环次数
LOP1: MOV AL,[SI] ;表中的数据按次序依次放入AL中
CMP AL,0 ;和0比较
JL LOP2 ;AL<0时转移
INC DL ;AL>=0,DL加一;统计大于等于0的个数
LOP2: INC SI ;修改地址指针(地址偏移量依次加一)
DEC CL ;循环次数CL减1
JNZ LOP1 ;ZF>0,CL不为0转移到LOP1
MOV RESULT,DL ;传送统计结果到存储单元
MOV AH,4CH
INT 21H ;返回DOS
CODE ENDS
END START
32..设一个字节的二进制数存放在BINNUM单元中。编写程序将它转换成十六进制数的形式显示在屏幕上。
分析:显示字符用DOS的2号功能调用,要显示的字符的ASCⅡ码必须装入DL中。因为4位二进制数对应1位十六进制数,一个字节的二进制数对应2位十六进制数。十六进制数每位代码是0~9和A~F,对应的ASCⅡ码为30H~39H和41H~46H,因此程序中要判断该数的大小,若在0~9范围,加上30H,若在A~F(10-15D)之间,则加上37H。
37H=30H+7H
解:程序清单如下:
DATA SEGMENT
BINSUM DB 10001011B
DATA ENDS
STACK SEGMENT PARA STACK
DB 100 DUP(?)
STACK ENDS
CODE SEGMENT
ASSUME CS:CODE,DS:DATA,SS:STACK ;段地址说明
START:MOV AX,DATA
MOV DS,AX ;数据段地址装填(堆栈段地址由系统装填)
MOV BL,BINSUM ;取二进制数
MOV DL,BL ;开始处理高4位
MOV CL,4 ;设置移位次数
SHR DL,CL ;右移4位,取高4位
ADD DL,30H ;转换成ASCⅡ码(一部分0-9)(A-F还不够,差7)
CMP DL,‘9’ ;与39H比较
JBE DONE1 ;小于等于39H转移
ADD DL,7 ;否则,为A-F,中则加7,转换为‘A’~‘F’
DONE1:MOV AH,2 ;显示高4位
INT 21H
AND BL,0FH ;开始处理低4位
MOV DL,BL
ADD DL,30H ;转换成ASCⅡ码(一部分0-9)(A-F还不够,差7)
CMP DL,41H ;和‘A’比较
JB LOP2 ;小于‘A’时,为0-9,则转移
ADD DL,7 ;否则,为A-F,则加7,转换为‘A’~‘F’
LOP2: MOV AH,2 ;显示低4位
INT 21H
MOV AH,4CH
INT 21H ;返回DOS
CODE ENDS
END START
33.编写一个汇编程序,求1~100的累加和。
分析:程序功能简单,循环次数已经确定为100次,可以采用循环结构实现它。
CODE SEGMENT
ASSUME CS:CODE
START: MOV AX,0 ;和清零
MOV CX,100 ;设置循环次数
LOP1: ADD AX,CX ;求累加和
LOOP LOP1 ;CX减1不为0,则转移
MOV AH,4CH
INT 21H ;返回DOS
CODE ENDS
END START
34.设VARY中有一组8位的符号数,编程统计其中的正数、负数、零的个数,分别存入VM、VN、VK变量中。
分析:数组VARY中的数据个数用CNT EQU $-VARY求出,则循环次数为CNT次。将数组VARY中的数据逐个与0比较,利用FR(标志寄存器)中的ZF求出零的个数,利用SF求出正、负数的个数。
解:参考程序如下:
STACK SEGMENT PARA STACK
DW 20H DUP(0)
STACK ENDS
DATA SEGMENT
VARY DB 23H,78H,0ABH,0CDH,00H,56H
DB 14H,86H,0EFH,0BCH,00H,0C0H
CNT EQU $-VARY ; $为末尾数后一位的地址,总数据个数,即循环次数
VM DB ?
VN DB ?
VK DB ?
DATA ENDS
CODE SEGMENT
ASSUME CS:CODE,DS:DATA,SS:STACK
START:MOV AX,DATA
MOV DS,AX ;数据段地址装填(堆栈段地址由系统装填)
MOV BX,0 ;初始化
MOV DL,0 ;清0
LEA SI,VARY ;初始化地址指针
MOV CX,CNT ;设置循环次数
;循环体
LOP1:CMP BYTE PTR [SI],0 ;和0比较
JE ZERO ;等于0转ZERO
JS LOP2 ;为负数转LOP2
INC BH ;统计正数个数的寄存器增1
JMP NEXT
LOP2:INC BL ;统计负数个数的寄存器增1
JMP NEXT
ZERO:INC DL ;统计0个数的寄存器增1
NEXT:INC SI ;修改地址指针
LOOP LOP1 ;判断终止条件,CX自减1,CX≠0则循环
;结束处理部分
MOV VM,BH ;保存正数的个数
MOV VN,BL ;保存负数的个数
MOV VK,DL ;保存0的个数
MOV AH,4CH
INT 21H ;返回DOS
CODE ENDS
END START
35.编写程序,实现在同一行上依次显示26个大写字母 .
CODE SEGMENT
ASSUME CS:CODE
START:MOV CX,26 ;设置循环次数
MOV DL,‘A’ ;要显示的字符的ASCⅡ码必须装入DL中
LOP1: MOV AH,2 ;显示字符用DOS的2号功能调用
INT 21H
INC DL ;循环修改部分,依次选择A、B、C….
LOOP LOP1 ;CX减1不为0,则转移
MOV AH,4CH
INT 21H ;返回DOS
CODE ENDS
END START
36.编写程序,实现键入任意一个字符,显示其ASCⅡ码中含“1”的个数。
CODE SEGMENT
ASSUME CS:CODE
START:MOV DL,0 ;计数器清0
MOV AH,1 ;等待键入一个字符,键入的字符存放在AL中
INT 21H
LOP1: CMP AL,0 ;与0比较
JE EXIT ;是0则转移到EXIT
SHL AL,1 ;左移1位,高位进入CF
ADC DL,0 ;统计1的个数
JMP LOP1
EXIT: ADD DL,30H ;二进制转换成ASCⅡ码
MOV AH,2 ;显示字符键入字符中含“1”的个数
INT 21H
MOV AH
展开阅读全文