微机原理期末考试汇编必备x段程序.docx
《微机原理期末考试汇编必备x段程序.docx》由会员分享,可在线阅读,更多相关《微机原理期末考试汇编必备x段程序.docx(18页珍藏版)》请在冰豆网上搜索。
微机原理期末考试汇编必备x段程序
北京邮电大学微机原理期末考试汇编必备x段程序来源:
张克终西秦人的日志
1.数据传送:
问题描述:
设在DS=3000H,偏移地址为0100H的内存中顺序存放着100个字节的数据。
要求传送到以2000H为起始偏移地址的区域。
代码:
利用寄存器间接寻址来寻找操作数可以编程如下:
mov ax,3000h
mov ds,ax ;建立数据段
mov si,0100h ;建立源数据指针
mov di,2000h ;建立目的地指针
mov cx,100 ;设置计数器
nt:
mov al,[si] ;取数
mov [di],al ;送数
inc si ;调整指针
inc di
dec cx ;计数器减1
jne nt ;CX-1≠0转nt标号
另一种方法:
提示:
若将倒数第2、3行用REP MOVSB代替,则可进一步简化。
MOV AX,3000H
MOV DS,AX
MOV ES,AX
MOV SI,0100H
MOV DI,0200H
MOV CX,100
CLD
NT:
MOVSB
LOOP NT
INT 20H
2.多字节的加法:
问题描述:
有两个4字节的无符号数相加,这两个数分别放在2000H和3000H开始的存储单元中,低位在前,高位在后。
运算后,得到的和放在2000H开始的内存单元中。
代码:
MOV SI,2000H ;取第一个数的首地址
MOVAX,[SI] ;将第一个数的低16位取到AX
MOV DI,3000H ;取第二个数的首地址
ADD AX,[DI] ;两个数的低16位相加。
MOV [SI],AX ;低16位相加的结果送到2000H和2001H单元
MOVAX,[SI+2] ;取第一个数的高16位送到AX中
ADC AX,[DI+2] ;两个数的高16位连同CF相加
MOV [SI+2],AX ;高16位相加的结果送到2002H,2003H单元。
3.多字节组合BCD码十进制加法
问题描述:
设第一个数据在1000H开始的8个内存单元中,第二个数据在2000H开始的8个内存单元中,要求相加之后将结果放在2000H开始的内存区域。
代码:
mov si,1000h ;SI指向第一个数据
mov di,2000h ;DI指向第二个数据
mov cx,8 ;共有8字节长
c1c ;清除进位标志
l1:
mov a1,[si] ;取第一个数据的1个字节
adc a1,[di] ;加上第二个数据的相应字节
daa ;对相加结果进行十进制调整
mov [di],a1 ;存到指定的内存区域
inc si ;指向下一个字节
inc di ;指向下一个字节
dec cx ;计数器减1
jnz l1 ;如未算完,则继续
int 20h ;返回DOS
4.多字节的移位
问题描述:
使BX所指的四个单元中的四字节数左移1位,
代码:
SAL WORD PTR [BX+0],l
RCL WORD PTR [BX+2],1
5.ASCII码转换为BCD码
问题描述:
设键盘输入的100个十进制数的ASCII码已在首地址DS为3000H,偏移量为0100H的内存区域中,要求把它们转换为组合型BCD码,高地址的放在高半字节。
存入偏移地址为0200H的区域中。
分析:
算法是这样的:
先将较低字节的32H转换为02H,再将较高字节的34H转变为40H,然后将其与02H按位相或成为42H。
循环50次完成50个字节的组合BCD码的转换。
代码:
MOV AX,3000H
MOV DS,AX
MOV SI,0100H
MOV DI,0200H
MOV CX,0032H
NEXT:
MOV AL,[SI]
INC SI
AND AL,0FH
MOV BL,AL
MOV AL,[SI]
INC SI
PUSH CX
MOV CL,4
SHL AL,CL
POP CX
ADD AL,BL
MOV [DI],AL
INC DI
LOOP NEXT
INT 20H
6.比较两个字符串
问题描述:
假设两个字符串分别放在DS段(设ES=DS)的str1和str2区域,其长度分别为L1和L2,比较这两个字符串是否相等。
若相等,则置M1单元内容为FFH,否则为00H。
代码:
提示:
前缀REPZ和REPE表示,当作比较的两字节(或字)相等时继续往下比较直至出现不等,或者CX减为0为止。
重复前缀使用前必须对CX置重复次数。
每比较一次,CX-1→CX(字比较CX-1→CX)。
CX=0表示两个字符串所有字节都比较过了,这时结束比较。
前缀REPNE和REPNZ则表示字节(字)不等时继续往下比较。
LEA SI,STR1
LEA DI,STR2
MOV CX,L1
CMP CX,L2
JNE UNEQ
CLD
REPZ CMPSB
JNE UNEQ
MOV AL,0FFH
JMP EXIT1
UNEQ:
MOV AL,00H
EXIT1:
MOV M1,AL
INT 20H
7.有条件的数据传送
问题描述:
将从BLOCK1单元开始的100个字节传送到BLOCK2单元开始的区域中,两区域的相对位置不确定。
数据传送过程中遇0DH(回车符)则结束传送。
假设DS=ES,即BLOCK1和BLOCK2同在一个数据段,并且位置不定(BLOCK1值可以大于、小于或等于BLOCK2)。
分析:
由于该题要求有条件传送,使用MOVSB指令不如LODSB和STOSB方便。
又因源数据区和目标数据区有可能重叠,所以应区分两种情况分别用地址增量和地址减量的方式来传送。
若源地址大于目的地地址,则应用地址增量方式从首地址开始传送,反之,则应用地址减量方式从末地址开始传送。
代码:
LEA SI,BLOCK1
LEA DI,BLOCK2
MOVCX,100
CMP SI,DI
JE DONE
JA DFO
STD
ADD SI,99
ADD DI,99
JMP TRAN
DFO:
CLD
TRAN:
LODSB
CMP AL,0DH
JE DONE
STOSB
LOOP TRAN
DONE:
INT 20H
8.确定字符串的长度
问题描述:
在STRING为始地址的字符串中搜索字符串结束符“$”,并将字符串的长度(不包括“$”)放入STRLN单元中;如果连续100个字节单元之中无“$”符则在STRLN单元中填入0FFH。
提示:
目标串搜索指令SCASB和SCASW将AL(或AX)与ES:
DI所寻址的字节(或字)内容进行比较而不改变其值;只影响标志位SF、ZF、PF、OF、CF、AF,并且修改DI指针使指向目标串中下一个元素。
代码:
LEA DI,STRING
MOV AL,‘$’
MOV CX,100
CLD
REPNE SCANSB
JZ DONE1
MOV AL,0FFH
JMP DONE2
DONE1:
MOV BX,100
SUB BX,CX
DEC BL
MOV AL,BL
DONE2:
MOV STRLN,AL
INT 20H
另一方法:
LEA DI,STRING
MOVAL,‘$’
MOV CX,100
DEC DI
L1:
INC DI
CMP AL,[DI]
LOOPNE L1
JZ DONE1
MOV AL,0FFH
JMP DONE2
DONE1:
MOV BX,100
SUB BX,CX
DEC BL
MOV AL,BL
DONE2:
MOV STRLN,AL
INT 20H
9.求符号数的最大值
问题描述:
设数据区1000H开始的区域中存放着50个字节的符号数。
要求找出其中最大的一个数并存到0FFFH单元。
代码:
MOV BX,1000H
MOV AL,[BX]
MOV CX,31H
L1:
INC BX
CMP AL,[BX]
JGE L2
MOV AL,[BX]
L2:
DEC CX
JNE L1
MOV BX,0FFFH
MOV [BX],AL
INT 20H
注:
如果是无符号数则把JGE L2换为JAE L2。
10.两个32位无符号数乘法
问题描述:
32位乘法需要做4次16位乘法,每次都要将部分积相加来实现,相加时则要注意位数对齐。
我们用连续的四个字单元来存放乘积,各部分积应加到适当单元。
分析:
data segment
num1 dw 8000h,8000h
num2 dw 8008h,8000h
mut dw4 dup(0)
data ends
stack segment stack’stack’
db100 dup (’s’)
stackends
code segment para ‘code’
assume cs:
code, ds:
data,
ss:
stack
proc far
push ds
xor ax,ax
pushax
movax,data
movds,ax
leabx,num1
movax,[bx] ;b→ax
movsi,[bx+4] ;d→si
movdi,[bx+6] ;c→di
mul si ;b*d
mov [bx+8],ax ;部分积1存于积单元中。
mov [bx+10],dx
mov ax,[bx+2] ;a→ax
mulsi ;a*d
add [bx+10],ax
adc [bx+12],dx
;带进位加入积2单元中
mov ax,[bx] ;b→ax
muldi ;b*c
add [bx+10],ax
;b*c加入积单元
adc [bx+12],dx
;带进位加至部分积3
adcwordptr[bx+14],0
;进位加至部分积4
mov ax,[bx+2] ;a→ax
muldi ;a*c
add[bx+12],ax
adc[bx+14],dx
ret
sta endp
code end
end sta
11.
datasegment
x dw 12
y dw ?
dataends
stacksegment stack‘stack’
db 100 dup (‘s’)
stack ends
codesegmentpara‘code’
assumecs:
code,ds:
data,ss:
stack
signprocfar
push ds
xorax,ax
push ax
mov ax,data
mov ds,ax
mov ax,x
and ax,ax ;建立标志
jz zero
jns plus
mov bx,0ffffh
jmp done
zero:
mov bx,0
jmpdone
plus:
mov bx,1
done:
mov y,bx
ret
sign endp
code ends
end sign
12.大散转
问题描述:
根据BUFFER单元的值,转到相应的子程序。
子程序的入口地址存放在转移表BRTAB中。
若BUFFER内容等于n,则转到第n个子程序(n从1~256,0代表256)。
代码:
datasegment
buffer db3
brtab dw 0000h,3000h
dw 0100h,3050h
dw 0000h,3090h
dw 0100h,4050h
dw 0000h,6000h
data ends
stack segmentstack‘stack’
db 100dup(‘s’)
stack ends
code segmentpara‘code’
assume cs:
code,ds:
data,ss:
stack
brch proc far
push ds
xor ax,ax
push ax
mov ax,data
mov ds,ax
lea bx,brtab
mov al,buffer
dec al
moav ah,0
shl ax,1 ;AL*2
shl ax,1 ;AL*4
add bx,ax
jmp dwordptr[bx]
ret
brch endp
code ends
end brch
13.数组求和
问题描述:
假设有一数组求和子程序SUM,试用这个子程序分别求出ARY1和ARY2两个数组的和,结果分别存入SUM1和SUM2字单元中。
代码:
datasegment
aryl db 03h,07h,50h,06h,23h,45h,0f6h,0dfh
len1equ $-ary1
sum1 dw ?
ary2db33h,44h,55h,12h,78h,89h,0feh,0cdh
len2 equ $-ary2
sum2 dw ?
dataends
stack segment stack‘stack’
db100dup(’s’)
stackends
codesegmentpara‘code’
assumecs:
codc,ds:
data,ss:
stack
sta proc far
push ds
xor ax,ax
push ax
mov ax,data
mov ds,ax
mov ax,len1
push ax
lea ax,ary1
push ax
call sum
mov ax,len2
push ax
lea ax,ary2
push ax
call sum
ret
sta endp
sum proc
push bp
mov bp,sp
push ax
push bx
push cx
pushf
mov cx,[bp+6] ;get array lenth
mov bx,[bp+4] ;get offset address
xor ax,ax ;sum=0
add1:
add al,[bx]
adc ah,0
inc bx
loop add1
mov [bx],ax
popf
pop cx
pop bx
pop ax
pop bp
ret4
sum endp
code ends
end sta
14.阶乘
问题描述:
确定变量NUMB的阶乘,把结果存入变量FNUMB。
变量NUMB的值大于0且小于8。
代码:
data segment
num db3
nj dw ?
data ends
stack segment stack‘stack’
db200dup(’s’)
stack ends
code segment para‘code’
assume cs:
code,ds:
data,ss:
stack
sta proc far
push ds
xorax,ax
push ax
mov ax,data
mov ds,ax
push cx
mov ah,0
mov a1,num
call factor
x1:
mov nj,ax
pop cx
ret
sta endp
factorproc
push ax
sub ax,1
jne fcon
pop ax
jmp retun
fcon:
call factor
x2:
pop cx
mul cl
Retun:
ret
factor endp
code ends
end sta
14.16进制数转换为ASCII码
CHANGE MACRO
LOCAL P1
CMP AL,10 ;如AL=0BH>0AH
JL P1 ;如AL ADD AL,‘A’-‘0’-10 ;0BH+(41H-30H-10)
P1:
ADD AL,‘0’ ;0BH+7+30H=42H=‘B’
ENDM
15.8253初始化
问题描述:
8253的OUT2输出2kHz频率波形,负脉冲宽度为1μs。
设CLK2输入1MHz的时钟GATE2接高电平,8253地址04~07H,
代码:
MOVAL,0B4H
OUT 07H,AL ;写入控制字
MOVAL,0F4H
OUT 06H,AL ;写入计数值的低8位
MOV AL,01H
OUT06H,AL ;写入计数值的高8位
也可以是:
MOVAL,0B5H ;二-十进制计数
OUT 07H,AL
MOV AL,00H
OUT 06H,AL
MOV A1,05H ;500=1F4H
OUT06H,AL
16.中断服务程序的编制
问题描述:
一个中断服务程序需要做的事情只是向端口340H