题目1
- 写一个完整的80X86汇编语言程序:键盘输入15个数据(转换成数值,存储到一维数组中,数值的长度为字),找出最小的偶数并在屏幕上显示,若没有偶数则显示“没有偶数!”。
.data
Number word 15 dup (?)
Mess byte “没有偶数!”
Input str1,10
Atoi, atod Ascii to double Ascii to Int
Atoi str1 ;ax
Atod str1 ;eax
Itoa str1,ax
Dtoa str1,eax
;求最小偶数
;作者:KUN.A.A
;date:2022/04/22
.386
.MODEL FLAT
ExitProcess PROTO NEAR32 stdcall, dwExitCode:DWORD
INCLUDE io.h
cr EQU 0dh ; carriage return character
LF EQU 0ah ; linefeed character
.STACK 4096 ; reserve 4096-byte stack
.DATA ; reserve storage for data
count WORD 1,0
Prompt1 BYTE "This program will find minest even number",0
Number BYTE 20 dup (?),0
Mess BYTE "Mei You Ou Shu",0
inputnum BYTE cr,Lf,"Enter Array",0
MaoHao BYTE ":",0
acount WORD 20 dup (?),0
result BYTE cr,Lf,"The minest even is:",0
minNum BYTE 20 dup (?),0
nbrArray WORD 100 dup (?),0
.CODE ; start of main program code
_start:
output Prompt1
mov ecx,15 ;循环15次
lea ebx,nbrArray
loopg:
output inputnum
itoa acount,count
inc count
output acount
output MaoHao
input Number,20
atod Number
mov [ebx],ax
add ebx,2
loop loopg
mov ecx,15
lea ebx,nbrArray
FINDEVEN:
mov al,[ebx] ;Test命令将两个操作数进行逻辑与运算,并根据运算结果设置相关的标志位。
test al,01H ;但是,Test命令的两个操作数不会被改变。运算结果在设置过相关标记位后会被丢弃。
jnz NEXT ;奇数跳转到NEXT,1与1相与为0
mov dx,[ebx] ;偶数存入EDX
jmp FINDMIN ;偶数跳转到FINDMIN
NEXT:
add ebx,2 ;单字节加2取下一位
loop FINDEVEN
;大于9FFFh的十六进制数据A000H、A001H...FFFEH、FFFFH等,在书写的时候都是以字母开头的。
mov dx,0FFFFH ;而在汇编程序中,数据不能以字母开头,都要在前面加0。
jmp EXIT ;没有偶数的时候跳转到EXIT输出没有偶数
FINDMIN: ;找到最小偶数
mov ecx,15
lea ebx,nbrArray
FIND:
mov al,[ebx]
test al,01H
jnz NEXT2 ;奇数跳转到NEXT2
cmp dx,[ebx] ;判断偶数的大小
jb NEXT2 ;小于也跳转到NEXT2
mov dx,[ebx]
NEXT2:
add ebx,2 ;下一个数字循环继续比较
loop FIND
output result
itoa minNum,dx
output minNum
jmp FINISH
EXIT: ;没有偶数
output Mess
FINISH: ;程序出口
INVOKE ExitProcess, 0 ; exit with return code 0
PUBLIC _start ; make entry point public
END ; end of source code
结果
有最小偶数2时
结果2:无偶数时
题目2
从键盘输入10个数据,存入一维数组中,并求出该数组的平均值显示在屏幕上。
;求平均值
;作者:KUN.A.A
;date:2022/04/22
.386
.MODEL FLAT
ExitProcess PROTO NEAR32 stdcall, dwExitCode:DWORD
INCLUDE io.h
cr EQU 0dh ; carriage return character
LF EQU 0ah ; linefeed character
.STACK 4096 ; reserve 4096-byte stack
.DATA ; reserve storage for data
count WORD 1,0
acount WORD 20 dup (?),0
Prompt1 BYTE "This program will Calculate average of 10 number",0
Number BYTE 20 dup (?),0
inputnum BYTE cr,Lf,"Enter Array",0
result BYTE cr,Lf,"The average is:",0
MaoHao BYTE ":",0
nbrArray DWORD 100 dup (?),0
.CODE ; start of main program code
_start:
output Prompt1
mov ecx,10 ;循环10次
lea ebx,nbrArray ;取首地址
loop1:
output inputnum ;说明语句
itoa acount,count
inc count
output acount ;输出数组次序
output MaoHao ;冒号输出
input Number,20 ;输入数字
atod Number
mov [ebx],eax
add ebx,4 ;取数组下一位,双字加4
loop loop1
mov ecx,10
lea ebx,nbrArray
mov edx,0 ;edx置0
loop2:
add edx,[ebx] ;取数组数字加入edx和
add ebx,4
loop loop2
mov eax,edx ;总和放入eax
cdq ;字长扩展4倍方便除法
mov ebx,10 ;除数放入ebx
idiv ebx ;有符号除法
dtoa nbrArray,eax ;商,即结果放入nbrArray
output result ;输出结果
output nbrArray
INVOKE ExitProcess, 0 ; exit with return code 0
PUBLIC _start ; make entry point public
END ; end of source code
结果:
test指令
test指令判断奇偶,将两个操作数进行逻辑与运算,并根据运算结果设置相关的标志位,Test命令的两个操作数不会被改变。运算结果在设置过相关标记位后会被丢弃。
lea指令
lea指令与EBX数组配合取数组首地址,并设置DUP数量防止运算时候溢出导致结果不符合预期。