mov dl,bl ;输出该字符和等号 int 21h
mov dl,‘=’ int 21h
mov ah,0 ;将该字符的ascii码送入ax mov al,bl
mov bl,10h ;准备除数bl=16
div bl ;相除后al为商,ah为余数
mov bx,ax ;暂存到bx中(bl为商,bh为余数) mov si,1 ;si为计数器
mov dl,bl ;利用dl计算,再进行输出 jmp lab3
lab4: mov dl,bh ;第2次输出余数时送bh
lab3: cmp dl,9 ;除16后,可能小于等于9,或大于9 ja lab2
add dl,30h ;小于9加30h转成数字字符的ascii码 jmp lab1
lab2: sub dl,10 ;大于9转成字母的ascii码 add dl,‘A’
lab1: mov ah,2 ;输出字符 int 21h
inc si ;计数器加1 cmp si,2
jbe lab4 ;比较后若小于等于2跳转,准备余数的计算和输出
mov dl,‘H’ ;输出字符H int 21h
mov ah,4ch ;控制权交还DOS int 21h code ends end main 4-24.答:
code segment assume cs:code main: mov ah,1
int 21h ;输入字符到al mov bl,al ;暂存到bl中 mov ah,2 ;回车换行 mov dl,13 int 21h
mov dl,10 int 21h
mov cx,8 ;设置循环计数器
lab1: mov al,bl ;准备被乘数al mov bl,2 ;准备乘数bl=2 mul bl ;相乘的积在ax中
mov bl,al ;低位al暂存到bl中,因为输出功能影响al mov dl,ah ;将高位ah输出 add dl,30h mov ah,2 int 21h
loop lab1 ;循环
mov ah,4ch ;控制权交还DOS int 21h code ends end main 4-25.答:
code segment assume cs:code main: mov ah,1
int 21h ;输入字符到al
mov bl,al ;输入字符暂存到bl中 mov ah,2 ;输出回车换行
mov dl,13 int 21h mov dl,10 int 21h
cmp bl,13 ;比较是否为回车键 jz lab1
mov dl,‘n’ jmp lab2
lab1: mov dl,‘y’ lab2: mov ah,2 int 21h
mov ah,4ch ;控制权交还DOS int 21h code ends end main 4-26.答:
code segment assume cs:code main: mov ah,1
int 21h ;输入字符到al mov bl,al ;暂存 mov ah,2 ;回车换行 mov dl,13 int 21h mov dl,10 int 21h
cmp bl,‘A’ ;和‘A’比较 jl lab1 ;小于‘A’跳转lab1输出‘*’,大于等于‘A’继续比较
cmp bl,‘Z’ ;和‘Z’比较 jle lab2 ;小于等于‘Z’表明为大写字母,跳转lab2求序号
cmp bl,‘a’ ;和‘a’比较
jl lab1 ;小于‘a’跳转lab1输出‘*’,大于等于‘a’继续比较
cmp bl,‘z’ ;和‘z’比较
jg lab1 ;大于‘z’跳转lab1输出‘*’,小于等于‘z’表明为小写字母
sub bl,‘a’-1 ;计算小写字母的顺序号 jmp lab3
lab2: sub bl,‘A’-1 ;计算大写字母的顺序号 lab3: mov ah,0 ;准备被除数ax mov al,bl
mov bl,10 ;准备除数bl
div bl ;十位在al中,个位在ah中 mov bx,ax ;将结果暂存到bx中 add bx,3030h mov ah,2
cmp bl,‘0’ ;若十位为‘0’,不输出 jz lab5
mov dl,bl ;输出十位 int 21h
lab5: mov dl,bh ;输出个位 int 21h jmp lab4
lab1: mov ah,2 ;输出‘*’号 mov dl,‘*’ mov al,2 int 21h
lab4: mov ah,4ch ;控制权交还DOS int 21h code ends end main
4-27.答: code segment assume cs:code
main: mov ah,1 ;输入三个字符分别放在cl,bl,al中 int 21h mov cl,al int 21h mov bl,al int 21h
cmp al,bl ;若al小于bl交换 jl lab1 xchg al,bl
lab1: cmp bl,cl ;若bl小于cl交换 jl lab2 xchg bl,cl lab2: cmp al,bl ;若al小于bl交换(注意:请考虑为何不比较al和cl) jl lab3 xchg al,bl
lab3: mov bh,al ;暂存al到bh中 mov ah,2 ;回车换行 mov dl,13 int 21h mov dl,10 int 21h
mov dl,bh ;顺序输出al(bh),bl,cl中的内容 int 21h mov dl,bl int 21h mov dl,cl int 21h
mov ah,4ch ;控制权交还DOS int 21h code ends end main
4-28.答: data segment
int1 db ‘935797238‘,’$‘ int2 db ‘843758912‘,’$‘ crlf db 13,10,‘$‘ data ends code segment
assume cs:code,ds:data main: mov ax,data mov ds,ax
mov ah,9 ;输出长整数int1 lea dx,int1 int 21h
lea dx,crlf ;回车换行 int 21h
lea dx,int2 ;输出长整数int2 int 21h
lea dx,crlf ;回车换行 int 21h
lea si,int1+8 ;将si指向int1的最低位 lea di,int2+8 ;将di指向int2的最低位
mov bl,0 ;bl用于记载对应位相加位的进位,初始值为0 mov cx,9
lab1: mov al,[di] ;取int2中的对应位 sub al,30h ;将字符转换为序号 add [si],al ;加到int1的对应位上 add [si],bl ;再加前一次的进位bl,相加后可能字符大于‘9‘,做如下处理:
mov bl,0 ;预置进位bl为0 cmp byte ptr [si],‘9‘ ;如果int1中对应位大于’9‘,则减10后,并重新对进位bl赋值为1. jbe lab2
sub byte ptr [si],10 mov bl,1
lab2: dec si ;指针后移并循环 dec di loop lab1
cmp bl,0 ;求得结果后,先处理进位bl,若为1输出,为0不输出. jz lab3 mov ah,2 mov dl,bl add dl,30h int 21h
lab3: mov ah,9 ;输出int1 lea dx,int1 int 21h mov ah,4ch int 21h code ends end main
4-29.答: data segment
buf db 80,81 dup(0) data ends code segment
assume cs:code,ds:data main: mov ax,data mov ds,ax
mov ah,10 ;输入字符串到buf lea dx,buf int 21h
mov bl,[buf+1] ;求字符串长度保存到bx中 mov bh,0
lea si,[buf+2] ;将si指向串首,di指向串尾 lea di,[buf+bx+1]
lab1: cmp si,di ;循环,如果si
lab2: mov ah,9 ;输出结果 lea dx,[buf+1]
mov byte ptr [buf+1],10
mov byte ptr [buf+bx+2],‘$‘ int 21h mov ah,4ch int 21h code ends end main
4-30.答: fata segment
k dw 123,425,0,-38,56,-76,19,28,25,-4 data ends code segment
assume cs:code,ds:data main: mov ax,data mov ds,ax
mov ax,[k] ;将第一个数放到ax中 mov bx,0 ;bx作为地址增量 mov cx,10 ;循环10次
lab1: cmp ax,[k+bx] ;若整数>ax,则ax重新赋值 jg lab2
mov ax,[k+bx] lab2: add bx,2 loop lab1
stc ;调用write子程序输出ax中的整数 call write mov ah,4ch int 21h
include write.asm code ends end main
4-31.答: data segment
k dw 123,425,0,-38,56,-76,19,28,25,-4 data ends code segment
assume cs:code,ds:data main: mov ax,data mov ds,ax mov bx,0 mov cx,10
lab1: cmp word ptr [k+bx],0 je lab2 add bx,2 loop lab1
lab2: cmp cx,0 jne lab3 mov di,-1 jmp lab4
lab3: add bx,2 shr bx,1 mov di,bx lab4: stc mov ax,di call write mov ah,4ch int 21h
include write.asm code ends end main
4-32.答: data segment
buf1 db 80,81 dup(0) buf2 db 80,81 dup(0) cr db 13,10,‘$‘ data ends code segment
assume cs:code,ds:data main: mov ax,data mov ds,ax mov ah,10 lea dx,buf1 int 21h
mov cl,[buf1+1] mov ch,0
lea si,buf1+2 lea di,buf2
lab1: cmp byte ptr [si],‘ ‘ je lab2 mov bl,[si] mov [di],bl inc di
lab2: inc si loop lab1
mov byte ptr [di],‘$‘ mov ah,9 lea dx,cr int 21h
lea dx,[buf2] int 21h mov ah,4ch int 21h code ends end main
4-33.答: data segment
buf1 db ‘The Ascii Code of $‘ buf2 db ‘ Is $‘ cr db 13,10,‘$‘ data ends code segment
assume cs:code,ds:data main: mov ax,data mov ds,ax lab1: mov ah,9 lea dx,buf1 int 21h mov ah,1 int 21h cmp al,13 je lab5 mov bl,al mov ah,9 lea dx,buf2 int 21h
mov si,1 ;si为计数器 lab2: mov al,bl
mov bl,10h ;准备乘数bl=16 mul bl ;相乘的积在ax中
mov bl,al ;低位al暂存到bl中,后续程序输出高位ah mov dl,ah ;利用dl计算,再进行输出
cmp dl,9 ;乘以16后,高位可能小于等于9,或大于9 ja lab3
add dl,30h ;小于9加30h转成数字字符的ascii码 jmp lab4
lab3: sub dl,10 ;大于9转成字母的ascii码 add dl,‘A‘
lab4: mov ah,2 ;输出字符 int 21h
inc si ;计数器加1 cmp si,2
jbe lab2 ;比较后若小于等于2跳转,准备下一位的输出mov ah,2 mov dl,‘H‘ int 21h mov ah,9 lea dx,cr int 21h
jmp lab1 lab5: mov ah,4ch int 21h code ends end main
4-34.答:
data segment ;数据段 msg0 db ‘Input error!$‘ msg1 db ’Input number1:$‘ msg2 db ’Input number2:$‘ data ends
sseg segment stack ;堆栈段 dw 64 dup(0) sseg ends
code segment ;代码段 assume cs:code,ds:data,ss:sseg
max proc near ;子程序“求两个数的大数” push bp ;入口参数:堆栈中存放两个数 mov bp,sp ;出口参数:大数在ax中 mov ax,word ptr [bp+6] cmp ax,word ptr [bp+4] jge mlab
mov ax,word ptr [bp+4] mlab: pop bp ret
max endp
main: mov ax,data mov ds,ax
mov ah,9 ;读取第一个数放在bx中 lea dx,msg1 int 21h clc
call read jc err mov bx,ax
mov ah,9 ;读取第二数放在ax中 lea dx,msg2 int 21h clc
call read jc err
push bx ;将两个数压入椎栈并调用子程序求两数
push ax call max
stc ;子程序结果在ax中,输出结果. call write
pop ax ;弹出栈中的两个数 pop bx jmp labe
err: mov ah,9 ;输入数据有错时的提示 lea dx,msg0 int 21h
labe: mov ah,4ch int 21h
include read.asm include write.asm code ends end main
4-35.答:
data segment ;数据段
buf dw 55,21,65,-21,0,32,123,-43,-23,11 msg1 db ‘before sort:$‘ msg2 db ‘sorted:$‘ data ends
sseg segment stack ;堆栈段 dw 64 dup(0) sseg ends code segment ;代码段 assume cs:code,ds:data,ss:sseg
sort proc near ;排序子程序 push ax ;保护现场 push bx push dx push ds
cmp cx,0 ;若cx小于或等于0,即没有任何数据,输出错误提示。 jg sor0 push cs pop ds
lea dx,err1 mov ah,9 int 21h jmp sor4
sor0: dec cx ;冒泡排序,cx减1设置外循环次数,若为0,表明只有一个数,转sor4返回。 jz sor4
sor1: push cx ;将外循环次数压入栈中保存。内循环的次数cx等于外循环次数
mov bx,0 ;地址偏移的变量 sor2: mov ax,[si+bx+2] ;两个数比较,若第1数大于第2数,则交换。并通过循环完成一趟冒泡。 cmp [si+bx],ax jle sor3
xchg [si+bx],ax mov [si+bx+2],ax sor3: add bx,2 loop sor2
pop cx ;弹出外循环的cx,通过loop使外循环次数减1,继续下一趟冒泡。 loop sor1
sor4: pop ds ;恢复现场 pop dx pop bx pop ax ret
err1 db ‘sort err:n<=0$’ ;定义错误提示的变量 sort endp
outp proc ;输出子程序。入口参数为“ds:si指向变量的入口地址,cx存放输出的元素个数。” push ax ;保护现场 push bx push dx push ds cmp cx,0 ;元素个数小于或等于0时,输出错误提示。jg out0 push cs pop ds
lea dx,err2 mov ah,9 int 21h jmp out2
out0: mov bx,0 ;地址偏移的变量 out1: mov ax,[si+bx] ;将数据放在ax中,调用write子程序输出。 Stc
call write
mov ah,2 ;输出空格 mov dl,’ ‘ int 21h
add bx,2 ;偏移量下移,并利用循环输出数据。 loop out1
out2: pop ds ;恢复现场
pop dx pop bx pop ax ret
err2 db ‘output err:n<=0$’ outp endp
main: mov ax,data ;主程序 mov ds,ax
mov ah,9 ;输出排序前的数据 lea dx,msg1 int 21h lea si,buf mov cx,10 call outp
lea si,buf ;调用排序子程序 mov cx,10 call sort call cr
mov ah,9 ;输出排序后的数据 lea dx,msg2 int 21h lea si,buf mov cx,10 call outp mov ah,4ch int 21h
include write.asm include cr.asm code ends end main
4-36.答:
data segment ;数据段 msg1 db ‘Yes$’ msg2 db ‘No$’ data ends
sseg segment stack ;堆栈段 dw 64 dup(0) sseg ends
code segment ;代码段 assume cs:code,ds:data,ss:sseg
shushu proc near ;判断是否为素数子程序。入口参数为“ax”,出口参数为“cf=1为素数,cf=0不是素数,ax保存原数。” push bx ;保护现场 push cx push dx
cmp ax,1 ;若数据为1或2时,则为素数。否则大于2时,则应利用除法判断。 jz ss1 cmp ax,2 jz ss1
mov cx,2 ;设置除数cx,循环从2一直到ax-1。 mov bx,ax ;被除数暂存到bx中
ss0: mov dx,0 ;利用dx,ax除以cx,判断余数dx是否为0。 mov ax,bx div cx cmp dx,0 ;余数为0,非素数。余数不为0,除数加1后,继续利用除法判断。 jz ss2 inc cx
cmp cx,bx ;判断除数是否大于原数 jl ss0
mov ax,bx ;将原数重新送回ax ss1: stc jmp ss3
ss2: mov ax,bx ;将原数重新送回ax clc
ss3: pop dx ;恢复现场 pop cx pop bx ret
shushu endp
main: mov ax,data mov ds,ax
call read ;读取一个数据到ax中
call shushu ;利用子程序判断是否为素数,结果在cf中。 jc lab1 lea dx,msg2 jmp lab2
lab1: lea dx,msg1 lab2: mov ah,9 int 21h mov ah,4ch int 21h
include read.asm code ends end main
4-37.答:
data segment ;数据段 buf db 13,10,’Input error!$’ msg1 db ‘One:$’ msg2 db ‘Two:$’ msg3 db ‘Result:$’ data ends
sseg segment stack ;堆栈段 dw 64 dup(0) sseg ends
code segment ;代码段 assume cs:code,ds:data,ss:sseg
maxgys proc near ;求最大公约数的递归子程序。入口参数“ax,bx保存两个正整数”,出口参数“ax”为最大公约数。 push cx push dx
glab1:mov dx,0 ;利用辗转相除法求最大公约数 div bx cmp dx,0 jz glab2 mov ax,bx mov bx,dx call maxgys
glab2:mov ax,bx pop dx pop cx ret
maxgys endp
main: mov ax,data mov ds,ax lea dx,msg1 mov ah,9 int 21h clc
call read jc err mov bx,ax lea dx,msg2 mov ah,9 int 21h clc