汇编原理实验 --计算平均数

先不考虑用户输入以及输出,我们可以根据一些总结来的经验得出:在处理数组累加,以及求平均值的程序中需要用到循环,把用户输入的数字加起来,然后除以一个总数得到平均值。

了解了核心算法后,开始需要处理一些汇编细节,和其他高级语言不同,在汇编语言中用户输入的数字其实是字符,用ASCII保存的。例如用户输入18,实际上是输入’1’.’8’,对应的ASCII,31h,38h,如果想要进行运算,首先要把用户输入的’数字’转化为真正的数字才行,也就有了我们changeToNum子程序。具体实现思想比较简单,用户输入一串数字后,我们从数字最高位开始读,然后把读出来的存于dx,然后将ASCII转化成数字只要减去30h即可,存于ax。再读次高位,用相同方法处理成数字,然后ax10后再加上dx,反复如此,直到所有读完。

输出也是类似的,要把数字输出在屏幕上,需要把每位数字转化成ASCII码输出,每次循环整除以10,余数就是最低位,直到除到商为0。这就是 dispdec子程序

有了这三大块功能后,就可以来实现代码了:

定义一个sum变量来记录累加,用户每输入一个数字转化后就加到sum中,输入完成后sum再除以整数得平均数。最后将其输出


DATAS SEGMENT
    ;此处输入数据段代码
    message db 'average is:$'
    sum dw 0
    count equ 5   ;数字个数
    num db 3        ;最多两位数
    numlen db ?
    numfld db 3 dup(?)
DATAS ENDS

STACKS SEGMENT
    ;此处输入堆栈段代码
STACKS ENDS

CODES SEGMENT
    ASSUME CS:CODES,DS:DATAS,SS:STACKS
START:
    MOV AX,DATAS
    MOV DS,AX
    ;此处输入代码段代码
    mov bx,sum
    mov cx,count
again:
    mov ah,0ah
    lea dx,num
    int 21h
    call printnewline
    call changeToNum  ;入口numfld出口参数为ax
    add bx,ax
    loop again
    lea dx,message
    call print
    mov sum,bx
    mov ax,sum
    mov bx,count
    DIV bx
    mov dx ,ax
    call dispdec
    MOV AH,4CH
    INT 21H
    
print proc
    push ax
    mov ah,09h
    int 21h
    pop ax
    ret
print endp
;输出换行
printnewline proc
	push ax
	push dx
	mov ah,02h
	mov dl,0dh
	int 21h
	mov dl,0ah
	int 21h
	pop dx
	pop ax
	ret
printnewline endp    
changeToNum proc
push cx
push dx
push bx
    mov cl,numlen
    mov si,0
    mov ax,0
again1: 
    mov dl,[numfld+si]
    sub dl,30h
    inc si
    add ax,dx
    cmp cl,1
    je last 
    mov bl,10  
    MUL bl
    loop again1
last:
pop bx
POP dx
pop cx
	ret
changeToNum endp
;十进制输出,入口参数dx
dispdec proc
		push ax
		push bx
		push cx
		push dx
        mov ax,dx
        xor dx,dx
        mov bx,10
        mov cx,0
a:
        cmp ax,10
        jb ok
        div bx
        add dl,30h
        push dx
        xor dx,dx
        inc cx
        jmp a
ok:
        add al,30h
        push ax
        inc cx
b:
        pop dx
        mov ah,2
        int 21h
        loop b
        pop dx
        pop cx
        pop bx
        pop ax
        ret
dispdec endp
CODES ENDS
    END START


运行结果如图:


  • 4
    点赞
  • 68
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
8259是一种可编程中断控制器,它可以处理多个设备的中断请求。在计算机系统中,中断是一种非常重要的机制,可以使CPU不必等待一些外设的操作完成,从而提高了系统的效率。 8259最常见的应用是在IBM PC和兼容机中,它可以管理PC中的各种设备,如键盘、鼠标、硬盘、打印机等等。在8259中,有8个中断请求线(IRQ0-IRQ7),可以连接到不同的设备上。当设备需要CPU的处理时,会向8259发送一个中断请求信号,8259会将这个请求转发给CPU,CPU会暂停当前正在执行的程序,转而去处理中断程序。当中断程序执行完毕后,CPU会回到原来的程序继续执行。 在本实验中,我们将学习如何使用汇编语言编写8259的初始化程序,使其可以正确地处理中断请求。 首先,我们需要了解8259的一些基本概念和寄存器。 8259有两个级联的芯片,一个是主芯片(master),另一个是从芯片(slave)。主芯片的IRQ0-IRQ7可以连接到不同的设备上,而从芯片只能连接到主芯片的某一个IRQ上。当从芯片需要处理中断请求时,它会向主芯片发送一个中断请求信号,由主芯片将这个请求转发给CPU。 8259有两个重要的寄存器,一个是控制寄存器(ICW),另一个是中断屏蔽寄存器(IMR)。 控制寄存器(ICW)分为4个字节,分别是ICW1、ICW2、ICW3、ICW4。ICW1用于设置8259的工作方式,ICW2用于设置中断向量号,ICW3用于设置级联方式,ICW4用于设置一些特殊功能。在初始化8259时,需要写入这些寄存器的值,以完成8259的设置。 中断屏蔽寄存器(IMR)用于控制8259对中断请求的响应。当某个设备需要中断处理时,它会向8259发送一个中断请求信号,如果该设备所在的IRQ对应的IMR位被设置为1,则8259会忽略该请求。只有当该位被清零后,8259才会将请求转发给CPU。 下面是一个简单的8259初始化程序,可以将主芯片的IRQ0-IRQ7全部开启,并设置中断向量号为0x20-0x27。该程序的实现过程如下: 1. 关闭中断,以免在初始化过程中被其他中断打断。 2. 向8259的控制寄存器写入ICW1,设置8259的工作方式为初始化。 3. 向8259的控制寄存器写入ICW2,设置中断向量号为0x20-0x27。 4. 向8259的控制寄存器写入ICW3,设置主芯片的从芯片连接方式。 5. 向8259的控制寄存器写入ICW4,设置一些特殊功能。 6. 向8259的中断屏蔽寄存器写入初始值,使得所有中断请求都能被响应。 7. 打开中断,使得CPU能够响应中断请求。 下面是该程序的具体实现过程: ``` ; 8259初始化程序 ; 将主芯片的IRQ0-IRQ7全部打开 ; 中断向量号为0x20-0x27 section .text global init_8259 init_8259: cli ; 关闭中断 ; 初始化8259 mov al, 0x11 ; ICW1:初始化,边沿触发,级联8259 out 0x20, al mov al, 0x20 ; ICW2:中断向量号从0x20开始 out 0x21, al mov al, 0x04 ; ICW3:连接从芯片到IRQ2 out 0x21, al mov al, 0x01 ; ICW4:8086模式,正常EOI out 0x21, al ; 设置IMR,打开所有中断 mov al, 0x00 ; IMR初始化为0,使得所有中断请求都能被响应 out 0x21, al sti ; 打开中断 ret ``` 在上述程序中,我们使用了汇编语言的in/out指令向8259的寄存器中写入数据,从而完成了8259的初始化设置。 该程序的主要作用是将8259初始化为可用状态,以便处理各种设备的中断请求。在实际应用中,我们可以将该程序作为系统启动时的一部分,以保证系统能够正确地响应各种中断请求。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值