要求:
从键盘输入一批十进制数值数据,存入到数组array中,并重新显示出来;
求数组array中最大值、最小值以及总和并显示。
步骤:
- 从键盘输入的ascii,需要进行十进制—>二进制转换,要考虑正负数,有子程序read完成
- 准备好存放数据的array,假设是十个,需要循环调用read 需要二进制数转换成ascii,并显示:write 和 显示语句,也需要循环
- 一个循环来完成求最大,最小及和
结果:
代码:
; multi-segment executable file template.
data segment
; add your data here!
pkey db "press any key...$"
;数据
count = 10
array dw count dup(?) ;分配数据空间10*2=20字节,初值未定
wtemp dw ? ;替换
max dw ? ;最大
min dw ? ;最小
total dd ? ;和 双字
strmax db 'The max num is ',0
strmin db 'The min num is ',0
strtotal db 'Total num is ',0
str db 'please input 10 numbers: ',0
strarray db 'The array is ',0
ends
stack segment
dw 128 dup(0)
ends
code segment
start:
; set segment registers:
mov ax, data
mov ds, ax
mov es, ax
; add your code here
lea dx, pkey
mov ah, 9
int 21h ; output string at ds:dx
; wait for any key....
call dpcrlf
mov si,offset str
push si
call print
add sp, 2
;-------------------
;代码段(主程序)
mov cx, count ;设置循环次数
mov bx,offset array
again:
call read ;输入一个数据
mov [bx], ax ;存放出口参数
inc bx
inc bx ;bx+2,到下一个存放数据的地方
call dpcrlf ;回车换行
loop again
;-------------------
;代码段(主程序)
mov si,offset strarray
push si
call print
add sp, 2
mov cx, count ;设置循环次数
mov bx,offset array
again1:
mov ax, [bx] ;数组第一个值给ax
mov wtemp, ax ;将入口参数存放到共享变量
call write ;调用子程序,显示一个数据
inc bx
inc bx
mov dl, ' '
mov ah, 02h ;输出一个空格
int 21h
loop again1
call dpcrlf ;光标回车换行
;-------------------
; 求最大值,最小值,和
mov bx, 0
mov total, 0
mov ax, array[bx]
mov max, ax ;第一个数假设为最大值
mov min, ax
cwd ;字到双字符的扩展指令
mov word ptr total, ax ;字操作
mov word ptr total+2, dx ;
mov cx, count
dec cx ;循环次数
add bx, 2 ;取下一个数
find:
mov ax, array[bx]
cmp max, ax
jge fmin ;max>=ax,跳到fmin比较是否为比min小
mov max, ax
jmp next
fmin:
cmp min, ax
jle next ;min<=ax,跳到next
mov min, ax
next:
cwd
add word ptr total, ax
adc word ptr total+2, dx ;adc加上进位
add bx, 2 ;取下一个数
loop find ;
;---------------- 显示统计结果
mov ax, max
mov wtemp, ax
mov si,offset strmax ;输出打印提示信息
push si
call print
add sp, 2
call write
call dpcrlf
mov ax, min
mov wtemp, ax
mov si,offset strmin
push si
call print
add sp, 2
call write
call dpcrlf
mov si,offset strtotal
push si
call print
add sp, 2
mov ax, word ptr total+2 ;显示和高字
mov wtemp, ax
call write
mov ax, word ptr total ;显示和的低字
mov wtemp, ax
call write
call dpcrlf
;---------------- 程序结束
mov ax, 4c00h ; exit to operating system.
int 21h
;----------------子程序
read proc ;输入有符号十进制数
push bx ;保存寄存器,出口参数:AX
push cx ;负数用'-'引导
push dx
xor bx, bx ;bx保存结果,xor异或,相当于重置为0
xor cx, cx ;cx重置0
mov ah, 1 ;输入一个字符
int 21h
cmp al, '+' ;是"+",继续输入字符
jz read1 ;相等就跳到read1
cmp al, '-' ;是"-",设置-1标志
jnz read2 ;不相等就跳到read2
mov cx, -1
read1:
mov ah, 1 ;继续输入字符,存到AL为ASCII码值
int 21h
read2:
cmp al, '0'
jb read3 ;低于'0'跳到read3
cmp al, '9'
ja read3 ;大于'9'跳到read3
sub al, 30h ;0-9之间的字符,-30h则转换为十进制
;利用移位指令,实现数值乘10:BX←BX×10
shl bx, 1 ;若是输入两位的数字,则要算数左移一位,相当于×2
mov dx, bx
shl bx, 1
shl bx, 1
add bx, dx ;实现*10的效果
;
mov ah, 0
add bx, ax ;把数存在bx,继续输入字符是存在ax里的
jmp read1 ;继续输入字符
read3:
cmp cx, 0
jz read4 ;cx等于0跳到read4
neg bx ;求绝对值
read4:
mov ax, bx ;设置出口参数
pop dx
pop cx
pop bx
ret ;返回
read endp
;-----------------
write proc ;显示有符号十进制的子程序
push ax
push bx
push dx
mov ax, wtemp ;从共享共享变量中取出并显示
test ax, ax ;判断数据是零、正数或负数,Test对两个参数(目标,源)执行AND逻辑操作,并根据结果设置标志寄存器,结果本身不会保存。
jnz write1 ;不等于跳到write1
mov dl, '0' ;是零,显示"0"后退出
mov ah, 02
int 21h
jmp write5
write1:
jns write2 ;符号为正,跳到write2
mov bx, ax
mov dl, '-'
mov ah, 02
int 21h ;输出打印'-'时,ax的值会变,要先把ax的值保存给bx
mov ax,bx
neg ax ;数据求补,绝对值
write2:
mov bx, 10
push bx ;10压入堆栈,作为退出标志
write3: ;write3的功能是把正数从个位数开始一个个压入栈中
cmp ax, 0 ;判断数据(商)是否为零
jz write4 ;等于0表示每一位数都取完了,跳到write4输出打印
sub dx, dx ;扩展被除数DX.AX,dx暂存余数,每做完一次就清0
div bx ;数据除以10:DX.AX÷10,ax存商,dx存余数
add dl,30h ;余数加30h,为ASCII的相应数字码
push dx ;数据各位先低位后高位压入堆栈
jmp write3
write4:
pop dx ;数据各位先高位后低位弹出堆栈
cmp dl, 10
je write5 ;是结束标志10,则退出
mov ah, 02
int 21h
jmp write4
write5:
pop dx
pop bx
pop ax
ret
write endp
dpcrlf proc ;光标回车换行的子程序
push ax
push dx
mov ah, 2
mov dl, 0dh
int 21h
mov ah, 2
mov dl, 0ah
int 21h
pop dx
pop ax
ret
dpcrlf endp
print proc ;输出打印字符串子程序
push bp
mov bp, sp
push ax
push dx
mov si, [bp+4]
dsp1:
mov dl, [si]
cmp dl, 0
jz dsp2
mov ah, 02
int 21h
inc si
jmp dsp1
dsp2:
pop dx
pop ax
pop bp
ret
print endp
ends
end start ; set entry point and stop the assembler.