📄 汇编代码.txt
字号:
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
6.7 编写递归子程序,求两个正整数的最大公约数。
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
call read
jc err
call maxgys
mov bx,ax
mov ah,9
lea dx,msg3
int 21h
mov ax,bx
clc
call write
jmp lab
err: lea dx,buf
mov ah,9
int 21h
lab: mov ah,4ch
int 21h
include write.asm
include read.asm
code ends
end main
6.8 编写递归子程序,求下面的数列的第n项。(费波那契数列)
f segment stack ;堆栈段
dw 512 dup(0)
f ends
code segment ;代码段
assume cs:code,ss:f
fibo proc near ;求费波那契数列第n项子程序。入口参数:项n压入到栈中。出口参数:结果在ax中。
push bp
mov bp,sp
push bx
mov bx,[bp+4] ;将项n弹出并保存到bx中
cmp bx,2 ;项n和2比较
jg f1 ;若项n大于2,则转f1求项n,否则结果保存到ax为1。
mov ax,1
jmp f2
f1: push cx ;现场保扩护
dec bx ;令bx-1,并求f(n-1)项的结果,暂存到cx中。
push bx
call fibo
mov cx,ax
dec bx ;继续让bx-1,并求f(n-1)项的结果,保存到ax中。
push bx
call fibo
add ax,cx ;求f(n)项,即为f(n-1)+f(n-2)。
pop bx ;恢复现场
pop bx
pop cx
f2: pop bx
pop bp
ret
fibo endp
main: call read ;输入所求项n
push ax ;将项n压入到栈中
call fibo ;调用子程序求第n项
clc
call write ;输出第n项
mov ax,4c00h
int 21h
include read.asm
include write.asm
code ends
6.9 为下面的问题设计子程序的入口参数和出口参数
(1) 求比x大的下一个素数
data segment ;数据段
msg0 db 'Input error!$'
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
jz ss1
cmp ax,2
jz ss1
mov bx,ax
mov cx,2
ss0: mov dx,0
mov ax,bx
div cx
cmp dx,0
jz ss2
inc cx
cmp cx,bx
jl ss0
mov ax,bx
ss1: stc
jmp ss3
ss2: mov ax,bx
clc
ss3: pop dx
pop cx
pop bx
ret
shushu endp
main: mov ax,data
mov ds,ax
clc
call read
inc ax
lab1: call shushu
jc labe
inc ax
jmp lab1
labe: clc
call write
mov ah,4ch
int 21h
include read.asm
include write.asm
code ends
end main
(2) 求3个带符号整数的平均值(不计余数)
7.2 编写一个子程序,以AX为入口参数,把AX中的各个二进制位颠倒次序后还放回AX中。比如,入口参数AX=101100011110100B,则处理后AX应为1001011110001101B。
code segment
assume cs:code
chag proc near ;颠倒AX的子程序。入口参数:AX,出口参数:AX
push bx
push cx
mov bx,ax
mov cx,16
ch1: shl ax,1
rcr bx,1
loop ch1
mov ax,bx
pop cx
pop bx
ret
chag endp
disp proc near ;按二进制显示AX中的数据。入口参数:AX。
push ax
push bx
push cx
push dx
mov cx,16
dp1: shl ax,1
mov bx,ax
jc dp2
mov dl,'0'
jmp dp3
dp2: mov dl,'1'
dp3: mov ah,2
int 21h
mov ax,bx
loop dp1
pop dx
pop cx
pop bx
pop ax
ret
disp endp
main: mov ax,1011000111101001B ;主程序
call disp
call chag
call cr
call disp
mov ah,4ch
int 21h
include cr.asm
code ends
end main
7.3 编写子程序,入口参数是一个字型数据,统计该字的16个二进制位中含有多少个1和多少个0。
code segment
assume cs:code
count proc near ;统计AX中二进制数据的1和0个数。入口参数:AX,出口参数:1的个数在bh中,0的个数在bl中。
push ax
push cx
xor bx,bx
mov cx,16
co1: shl ax,1
jc co2
inc bl
jmp co3
co2: inc bh
co3: loop co1
pop cx
pop ax
ret
count endp
main: mov ax,1011000111101001B
call count
mov al,bh
mov ah,0
call write
mov ah,2
mov dl,','
int 21h
mov al,bl
mov ah,0
call write
mov ah,4ch
int 21h
include write.asm
code ends
end main
7.4 编写完整程序,调用第6章的read子程序,从键盘读入一个带符号整数,以二进制输出其补码。
code segment
assume cs:code
disp proc near
push ax
push bx
push cx
push dx
mov cx,16
dp1: shl ax,1
mov bx,ax
jc dp2
mov dl,'0'
jmp dp3
dp2: mov dl,'1'
dp3: mov ah,2
int 21h
mov ax,bx
loop dp1
pop dx
pop cx
pop bx
pop ax
ret
disp endp
main: clc
call read
call disp
mov ah,4ch
int 21h
include read.asm
code ends
end main
.model small
.stack
.data
bvar DB 16
wvar DW 4*3
dvar DD 4294967295 ;=232-1
qvar DQ ?
DB 1,2,3,4,5
tvar DT 2345 ;定义了BCD码2345H
abc DB 'a','b','c'
msg DB 'Hello',13,10,'$'
bbuf DB 12 DUP('month')
dbuf DD 25 DUP(?)
CALLDOS EQU <int 21h>
.model tiny ;微型存储模式
.code ;只有代码段
.startup ;程序起始点,= ORG 100H
mov dx,offset string
mov ah,9 ;显示字符串信息
int 21h
mov ah,01h ;等待按键
int 21h
mov ah,02h ;响铃
mov dl,07h
int 21h
.exit 0 ;程序结束点,返回DOS
string db ‘Press any key to continue !$’
;数据安排在此
end ;汇编结束
判断有无实根
.startup
mov al,_b
imul al
mov bx,ax ;BX中为b2
mov al,_a
imul _c
mov cx,4
imul cx ;AX中为4ac(DX无有效数据)
cmp bx,ax ;比较二者大小
jge yes ;条件满足?
mov tag,0
;第一分支体:条件不满足,tag←0
jmp done ;跳过第二个分支体
yes: mov tag,1
;第二分支体:条件满足,tag←1
done: .exit 0
求和
.model small
.stack 256
.data
sum dw ?
.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
end
大小写
mov bx,offset string
again: mov al,[bx] ;取一个字符
or al,al ;是否为结尾符0
jz done ;是,退出循环
cmp al,'A' ;是否为大写A~Z
jb next
cmp al,'Z'
ja next
or al,20h
;是,转换为小写字母(使D5=1)
mov [bx],al ;仍保存在原位置
next: inc bx
jmp again ;继续循环
done: .exit 0
冒泡法
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 ;外循环尾
无参数传递的子程序
;子程序功能:实现光标回车换行
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 ;过程结束
ALdisp proc ;实现al内容的显示
push ax ;过程中使用了AX、CX和DX
push cx
push dx
push ax ;暂存ax
mov dl,al ;转换al的高4位
mov cl,4
shr dl,cl
or dl,30h ;al高4位变成3
cmp dl,39h
jbe aldisp1
add dl,7 ;是0Ah~0Fh,还要加上7
aldisp1: mov ah,2 ;显示
int 21h
pop dx ;恢复原ax值到dx
and dl,0fh ;转换al的低4位
or dl,30h
cmp dl,39h
jbe aldisp2
add dl,7
aldisp2: mov ah,2 ;显示
int 21h
pop dx
pop cx
pop ax
ret ;过程返回
ALdisp endp
... ;主程序,同例4.8源程序
mov bx,offset array;调用程序段开始
mov cx,count
displp: mov al,[bx]
call ALdisp ;调用显示过程
mov dl,',' ;显示一个逗号,分隔数据
mov ah,2
int 21h
inc bx
loop displp ;调用程序段结束
.exit 0
... ;过程定义
end
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -