汇编 | 子程序设计求最大值最小值总和

要求:
从键盘输入一批十进制数值数据,存入到数组array中,并重新显示出来;
求数组array中最大值、最小值以及总和并显示。

步骤:

  1. 从键盘输入的ascii,需要进行十进制—>二进制转换,要考虑正负数,有子程序read完成
  2. 准备好存放数据的array,假设是十个,需要循环调用read 需要二进制数转换成ascii,并显示:write 和 显示语句,也需要循环
  3. 一个循环来完成求最大,最小及和

结果:
在这里插入图片描述
代码:

; 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.

  • 3
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值